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 心跳动画的主要内容,如果未能解决你的问题,请参考以下文章

UIButton在动画期间没有交互

UIButton移动动画

动画 UIButton 背景图像

在 UITableViewCell 中为自定义 UIButton 设置动画

动画期间 UIButton 的 CGRectContainsPoint

自定义动画后的 UIButton 动作