【问题标题】:UIButton Heartbeat AnimationUIButton 心跳动画
【发布时间】: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()

}

【问题讨论】:

    标签: swift animation


    【解决方案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")
            }
          

          希望这会有所帮助。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-08-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多