2016-01-11 127 views
6

我爲UIButton創建了心跳動畫。但是,無法停止此動畫,因爲它是無限的代碼循環。修改了衆多的UIView動畫代碼塊後,我一直無法獲得UIViewAnimationOptions.Repeat來生成我需要的東西。如果我能做到這一點,我可以簡單地button.layer.removeAllAnimations()刪除動畫。什麼是寫這個允許刪除動畫的方法?我正在考慮一個計時器,但這可能會讓多個動畫發生混亂。UIButton心跳動畫

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() 

} 

回答

18

這很好用。阻尼和彈簧需要稍微調整,但這可以解決問題。 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

+0

這是完美的謝謝:) – RichAppz

0

在你提到你希望動畫停止命令你原來的問題。我假設你也希望它也能從命令開始。這個解決方案既可以做,也可以很簡單。

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") 
    } 

希望這有助於。