问题
For some reason my animation is not waiting 10 seconds to execute. It is executing as soon as I lift the finger off the button and the button is not red animated.
SomeClass: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
tapBeatButton.addTarget(self, action: #selector(tapBeatButtonTouchedDown), for: UIControl.Event.touchDown)
tapBeatButton.addTarget(self, action: #selector(tapBeatButtonTouchedUpInside), for: UIControl.Event.touchUpInside)
}
@objc func tapBeatButtonTouchedDown() {
print("it's red")
//keep it red for 10 seconds, then make it blue
UIView.animate(withDuration: 10.0, animations: {
// it does not wait 10 seconds. It executes immediately
self.tapBeatButton.setImage(#imageLiteral(resourceName: "icon-beat-selected"), for: .normal)
},completion: { _ in
self.tapBeatButton.setImage(#imageLiteral(resourceName: "icon-beat-unselected"), for: .normal)
print("out")
})
}
@objc func tapBeatButtonTouchedUpInside() {
print("it's blue ")
tapBeatButton.setImage(#imageLiteral(resourceName: "icon-beat-unselected"), for: .normal)
}
}//end class
回答1:
You'd be best off subclassing your UIButton for this kind of behavior.
class MyImageButton: UIButton {
private var firstImage: UIImageView = {
let iv = UIImageView()
iv.image = UIImage(named: "my_image_1")
iv.contentMode = .center
iv.translatesAutoresizingMaskIntoConstraints = false
iv.heightAnchor.constraint(equalToConstant: 48.0).isActive = true
iv.widthAnchor.constraint(equalToConstant: 48.0).isActive = true
return iv
}()
private var secondImage: UIImageView = {
let iv = UIImageView()
iv.image = UIImage(named: "my_image_2")
iv.contentMode = .center
iv.translatesAutoresizingMaskIntoConstraints = false
iv.heightAnchor.constraint(equalToConstant: 48.0).isActive = true
iv.widthAnchor.constraint(equalToConstant: 48.0).isActive = true
// this one starts invisible
iv.alpha = 0.0
return iv
}()
init() {
super.init(frame: CGRect())
// Hard coding height and width here. Feel free to set using frame instead.
self.translatesAutoresizingMaskIntoConstraints = false
self.heightAnchor.constraint(equalToConstant: 56.0).isActive = true
self.widthAnchor.constraint(equalToConstant: 56.0).isActive = true
self.addSubview(firstImage)
firstImage.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
firstImage.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
self.addSubview(secondImage)
secondImage.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
secondImage.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func transitionImages() {
// Swap which image is visible by setting them to be the opposite alpha values. Transition for 1 second.
UIView.animate(withDuration: 1.0) {
self.firstImage.alpha = self.firstImage.alpha == 0.0 ? 1.0 : 0.0
self.secondImage.alpha = self.secondImage.alpha == 0.0 ? 1.0 : 0.0
}
}
}
And then in your viewController:
class MyViewController: UIViewController {
override func viewDidLoad() {
let mybutton = MyImageButton()
mybutton.addTarget(self, #selector(transition), .touchUpInside)
// Constrain your button here:
mybutton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
mybutton.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
}
@objc private func transition() {
// Wait 10 secs before transitioning your images.
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0, execute: {
mybutton.transitionImages()
})
}
}
来源:https://stackoverflow.com/questions/56499230/how-to-set-uibutton-with-image-in-animation