Hi Claude31! Sorry for delay - was on vacation in suburb.
First thing:
On first touch, what do you get from the print ?
print("executing: index: \(index), button: \(button.description)")
On first touch updateButtonSelectionStates procedure executes properly and i see this:
buttonPressed
executing: index: 0, button: <UIButton: 0x7fcf0cc22ec0; frame = (0 0; 20 20); opaque = NO; layer = <CALayer: 0x600000ed5a40>>
executing: index: 1, button: <UIButton: 0x7fcf0cc231e0; frame = (30 0; 20 20); opaque = NO; layer = <CALayer: 0x600000ed6400>>
executing: index: 2, button: <UIButton: 0x7fcf0cc23500; frame = (60 0; 20 20); opaque = NO; layer = <CALayer: 0x600000ed7fe0>>
executing: index: 3, button: <UIButton: 0x7fcf0cc23820; frame = (90 0; 20 20); opaque = NO; layer = <CALayer: 0x600000ed5160>>
executing: index: 4, button: <UIButton: 0x7fcf0cc23b40; frame = (120 0; 20 20); opaque = NO; layer = <CALayer: 0x600000ed5fa0>>
And nothing happens on user interface... But then i second time click on any button - ui updates regarding previouse button state (not current state).
Here my full code of RatingControl.swift
//
// RatingControl.swift
// HelloWorld.Foods
//
// Created by Romeo on 21/08/2019.
// Copyright © 2019 Romeo. All rights reserved.
//
import UIKit
@IBDesignable
class RatingControl: UIStackView {
/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
}
*/
// MARK: Properties
private var ratingButtons = [UIButton]()
var rating = 0 {didSet { updateButtonSelectionStates() }}
@IBInspectable
var starSize : CGSize = CGSize(width: 44.0, height: 44.0) {
didSet {
setupButtons()
}
}
@IBInspectable
var starCount : Int = 5 {
didSet {
setupButtons()
}
}
// MARK: Initialization
override init(frame: CGRect) {
super.init(frame: frame)
setupButtons()
}
required init(coder: NSCoder) {
super.init(coder: coder)
setupButtons()
}
// MARK: Private buttons
private func setupButtons()->Void {
let bundle = Bundle(for: type(of: self))
let emptyStar = UIImage(named: "emptyStar", in: bundle, compatibleWith: self.traitCollection)
let filledStar = UIImage(named: "filledStar", in: bundle, compatibleWith: self.traitCollection)
let highLightedStar = UIImage(named: "highLightedStar", in: bundle, compatibleWith: self.traitCollection)
for button in ratingButtons {
removeArrangedSubview(button)
button.removeFromSuperview()
}
ratingButtons.removeAll()
for _ in 0..<starCount {
let button = UIButton()
button.backgroundColor = UIColor.blue
//button.isUserInteractionEnabled = true
//button.setImage(emptyStar, for: .normal)
//button.setImage(filledStar, for: .selected)
//button.setImage(highLightedStar, for: .highlighted)
//button.setImage(highLightedStar, for: [.selected, .highlighted])
button.translatesAutoresizingMaskIntoConstraints = false
button.heightAnchor.constraint(equalToConstant: starSize.height).isActive = true
button.widthAnchor.constraint(equalToConstant: starSize.width).isActive = true
button.addTarget(self, action: #selector(RatingControl.ratingButtonTapped(button:)), for: UIControl.Event.touchUpInside)
addArrangedSubview(button)
ratingButtons.append(button)
}
}
//MARK: Button action
@objc func ratingButtonTapped(button: UIButton) {
print("buttonPressed")
guard let indexOfButton = ratingButtons.firstIndex(of: button) else {
fatalError("The button \(button) is not in the buttons array \(ratingButtons)")
}
let selectedIndex = indexOfButton + 1
if(selectedIndex == rating) {
rating = 0
} else {
rating = selectedIndex
}
}
func updateButtonSelectionStates() {
for (index, button) in ratingButtons.enumerated() {
print("executing: index: \(index), button: \(button.description)")
button.isSelected = index < rating
if button.isSelected {
button.backgroundColor = UIColor.red
} else {
button.backgroundColor = UIColor.blue
}
//button.backgroundColor = UIColor(red: 0.1, green: 0.80, blue: 0.1, alpha: 1.0)
button.setTitle("s", for: .selected)
//button.layoutIfNeeded()
button.superview?.superview?.layoutIfNeeded()
button.superview?.superview?.setNeedsDisplay()
button.superview?.setNeedsDisplay()
}
}
@objc
func testBtnUpdate()->Void {
print("testBtnUpdate()")
let t0 = ratingButtons.first?.isSelected
if let t1 = t0 {
ratingButtons.first?.isSelected = !t1
}
}
}