Your downside come from use of isHighlighted
‘s property, as Apple point out of their docs:
Controls routinely set and clear this state in response to
acceptable contact occasions. You’ll be able to change the worth of this property as
wanted to use or take away a spotlight programmatically
When your finger go inside button
, isHighlighted
might be true and vice-versa.
In ViewController
, you solely add goal to occasion .touchUpInside
so your perform will solely be known as when customers carry their finger in aspect button
.
To repair your downside, we have to change button's picture
at any time when it obtain .touchUpInside
occasion, as an alternative of rely upon isHighlighted
to alter button picture, you need to use isSelected
and toggle it when button
acquired contact up inside:
class TestViewController: UIViewController {
var button: SomeButtonWithImage = {
let button = SomeButtonWithImage(body: .init(x: 100, y: 200, width: 100, top: 100))
return button
}()
override func viewDidLoad() {
tremendous.viewDidLoad()
view.backgroundColor = .white
button.normalImage = "mute"
button.selectedImage = "unmute"
button.isSelected = false // <- set intial isSelected to render picture
button.addTarget(self, motion: #selector(self.rightButtonAction), for: .touchUpInside)
view.addSubview(button)
}
@objc func rightButtonAction() {
button.isSelected.toggle() // <-- toggle button isSelected right here
}
}
class SomeButtonWithImage: UIButton {
var buttonSelectedScale: CGFloat = 0.9
var buttonScaleDownDuration: TimeInterval = 0.15
var buttonScaleUpDuration: TimeInterval = 0.25
public var normalImage: String = ""
public var selectedImage: String = ""
override init(body: CGRect) {
tremendous.init(body: body)
backgroundColor = .pink
configuration = .plain()
configuration?.baseBackgroundColor = .clear
}
override var isSelected: Bool {
didSet {
if isSelected {
configuration?.picture = UIImage(named: self.selectedImage)
} else {
configuration?.picture = UIImage(named: self.normalImage)
}
}
}
override var isHighlighted: Bool {
didSet {
print(isHighlighted)
}
}
required init?(coder: NSCoder) { fatalError("error") }
personal func animateScale(to scale: CGFloat, length: TimeInterval) {
UIView.animate(withDuration: length, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, choices: [], animations: {
self.rework = .init(scaleX: scale, y: scale)
}, completion: nil)
}
override func touchesBegan(_ touches: Set, with occasion: UIEvent?) {
tremendous.touchesBegan(touches, with: occasion)
animateScale(to: buttonSelectedScale, length: buttonScaleDownDuration)
}
override func touchesEnded(_ touches: Set, with occasion: UIEvent?) {
tremendous.touchesEnded(touches, with: occasion)
animateScale(to: 1, length: buttonScaleDownDuration)
}
override func touchesCancelled(_ touches: Set, with occasion: UIEvent?) {
tremendous.touchesCancelled(touches, with: occasion)
animateScale(to: 1, length: buttonScaleDownDuration)
}
}