UIButton 心跳动画
Posted
技术标签:
【中文标题】UIButton 心跳动画【英文标题】:UIButton Heartbeat Animation 【发布时间】:2016-01-11 19:33:39 【问题描述】:我为 UIButton 创建了心跳动画。然而,没有办法停止这个动画,因为它是一个无限的代码循环。在修改了许多 UIView 动画代码块之后,我无法让UIViewAnimationOptions.Repeat
产生我需要的东西。如果我能做到这一点,我可以简单地 button.layer.removeAllAnimations()
删除动画。什么是写这个允许删除动画的方法?我可能在考虑一个计时器,但这可能会因为多个动画而有点混乱。
func heartBeatAnimation(button: UIButton)
button.userInteractionEnabled = true
button.enabled = true
func animation1()
UIView.animateWithDuration(0.5, delay: 0.0, options: [], animations: () -> Void in
button.transform = CGAffineTransformMakeScale(2.0, 2.0)
button.transform = CGAffineTransformIdentity
, completion: nil)
UIView.animateWithDuration(0.5, delay: 0.5, options: [], animations: () -> Void in
button.transform = CGAffineTransformMakeScale(2.0, 2.0)
button.transform = CGAffineTransformIdentity
) (Bool) -> Void in
delay(2.0, closure: () -> () in
animation2()
)
func animation2()
UIView.animateWithDuration(0.5, delay: 0.0, options: [], animations: () -> Void in
button.transform = CGAffineTransformMakeScale(2.0, 2.0)
button.transform = CGAffineTransformIdentity
, completion: nil)
UIView.animateWithDuration(0.5, delay: 0.5, options: [], animations: () -> Void in
button.transform = CGAffineTransformMakeScale(2.0, 2.0)
button.transform = CGAffineTransformIdentity
) (Bool) -> Void in
delay(2.0, closure: () -> () in
animation1()
)
animation1()
【问题讨论】:
【参考方案1】:这非常有效。阻尼和弹簧需要稍微调整,但这解决了问题。 removeAllAnimations()
清除动画并将按钮恢复到正常状态。
button.userInteractionEnabled = true
button.enabled = true
let pulse1 = CASpringAnimation(keyPath: "transform.scale")
pulse1.duration = 0.6
pulse1.fromValue = 1.0
pulse1.toValue = 1.12
pulse1.autoreverses = true
pulse1.repeatCount = 1
pulse1.initialVelocity = 0.5
pulse1.damping = 0.8
let animationGroup = CAAnimationGroup()
animationGroup.duration = 2.7
animationGroup.repeatCount = 1000
animationGroup.animations = [pulse1]
button.layer.addAnimation(animationGroup, forKey: "pulse")
这篇文章很有帮助:CAKeyframeAnimation delay before repeating
【讨论】:
【参考方案2】:Swift 5 代码,脉冲之间没有停顿:
let pulse = CASpringAnimation(keyPath: "transform.scale")
pulse.duration = 0.4
pulse.fromValue = 1.0
pulse.toValue = 1.12
pulse.autoreverses = true
pulse.repeatCount = .infinity
pulse.initialVelocity = 0.5
pulse.damping = 0.8
switchButton.layer.add(pulse, forKey: nil)
【讨论】:
【参考方案3】:我创造了这样的东西:
let animation = CAKeyframeAnimation(keyPath: "transform.scale")
animation.values = [1.0, 1.2, 1.0]
animation.keyTimes = [0, 0.5, 1]
animation.duration = 1.0
animation.repeatCount = Float.infinity
layer.add(animation, forKey: "pulse")
【讨论】:
【参考方案4】:关于您最初的问题,您提到您希望动画在命令下停止。我假设您也希望它在命令下启动。这个解决方案可以做到这两点,而且非常简单。
func cutAnim()
for view in animating
///I use a UIView because I wanted the container of my button to be animated. UIButton will work just fine too.
(view.value as? UIView)?.layer.removeAllAnimations()
func pulse(button: UIButton, name: String)
///Here I capture that container
let container = button.superview?.superview
///Add to Dictionary
animating[name] = container
cutAnim()
UIView.animate(withDuration: 1, delay: 0.0, options:[UIViewAnimationOptions.repeat, UIViewAnimationOptions.autoreverse, .allowUserInteraction], animations:
container?.transform = CGAffineTransform(scaleX: 1.15, y: 1.15)
///if you stop the animation half way it completes anyways so I want the container to go back to its original size
container?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
, completion: nil)
在任何地方调用 cutAnim() 以停止动画,如果需要,可以在计时器内。
要启动动画,请使用常规按钮操作
@IBAction func buttonWasTappedAction(_ sender: Any)
pulse(button: sender as! UIButton, name: "nameForDictionary")
希望这会有所帮助。
【讨论】:
以上是关于UIButton 心跳动画的主要内容,如果未能解决你的问题,请参考以下文章
在 UITableViewCell 中为自定义 UIButton 设置动画