swift - 如何在动画中设置带有图像的 UIButton?
问题描述
出于某种原因,我的动画没有等待 10 秒来执行。一旦我将手指从按钮上抬起并且按钮没有红色动画,它就会执行。
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
解决方案
对于这种行为,您最好将您的 UIButton 子类化。
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
}
}
}
然后在你的 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()
})
}
}
推荐阅读
- python-3.x - 如何在没有用户名和密码的情况下使用 LDAP3 进行简单搜索?
- javascript - 在 Highchart Gantt 中旋转 X 轴标签
- jdbc - 通过 DataGrip 连接到 Snowflake 时出现 JDBC 驱动程序错误
- javascript - 使用 forEach 循环分解函数
- reactjs - 从子组件更新 React 上下文
- github-actions - 依赖机器人:错误:.github#L1 `on` 中没有定义事件触发器
- outlook-redemption - Outlook 365 的 RDO 规则问题
- firefox - 如何拦截 Playwright 的 Firefox 图片请求
- javascript - 通过循环一个 javascript 对象来创建元素
- xcode - Xcode 13 AppleScript 框架无法将 UI 连接到 Applescript 代码