2017-07-25 102 views
0

我有一個開始/停止按鈕和我想要旋轉的圖像視圖。開始/停止圖像視圖旋轉動畫

當我按下按鈕時,我想要開始旋轉,當我再次按下按鈕時,圖像應該停止旋轉。我目前使用的是動畫UIView,但我還沒有想出停止視圖動畫的方法。

我想讓圖像旋轉,但是當動畫停止時,圖像不應該回到起始位置,而是繼續動畫。

var isTapped = true 

    @IBAction func startStopButtonTapped(_ sender: Any) { 
     ruotate() 
     isTapped = !isTapped 
    } 

    func ruotate() { 
     if isTapped { 
      UIView.animate(withDuration: 5, delay: 0, options: .repeat, animations: {() -> Void in 
      self.imageWood.transform =  self.imageWood.transform.rotated(by: CGFloat(M_PI_2)) 
      }, completion: { finished in 
      ruotate() 
      }) 
    } } 

這是我的代碼,但它不像我的方面工作。

+1

您可以使用'CABasicAnimation'來實現開始/停止動畫。 –

回答

5

斯威夫特3.X

開始動畫

let rotationAnimation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") 
    rotationAnimation.toValue = NSNumber(value: .pi * 2.0) 
    rotationAnimation.duration = 0.5; 
    rotationAnimation.isCumulative = true; 
    rotationAnimation.repeatCount = .infinity; 
    self.imageWood?.layer.add(rotationAnimation, forKey: "rotationAnimation") 

停止動畫

self.imageWood?.layer.removeAnimation(forKey: "rotationAnimation") 

斯威夫特2.x的

開始動畫

let rotationAnimation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") 
    rotationAnimation.toValue = NSNumber(double: M_PI * 2.0) 
    rotationAnimation.duration = 1; 
    rotationAnimation.cumulative = true; 
    rotationAnimation.repeatCount = .infinity; 
    self.imageWood?.layer.addAnimation(rotationAnimation, forKey: "rotationAnimation") 

停止動畫

self.imageWood?.layer.removeAnimation(forKey: "rotationAnimation") 
+2

這會按照你說的停止動畫,但該圖層會捕捉到它的最終位置。如果您希望在當前狀態下停止動畫,則需要採取額外的步驟:一種方法是從表示層獲取圖層變換,在實際圖層上設置變形,然後刪除動畫。另一種選擇是將動畫的動畫速度設置爲零。 –

+0

@DuncanC感謝您的建議,同時我邀請您以另一種方式編輯答案.. !! –

+0

我剛剛發佈了一個備用解決方案的答案。 –

1

你的代碼,使圖像旋轉的2PI的角度,但如果你點擊按鈕的同時旋轉不會結束,動畫將在停止之前完成,這就是爲什麼它會進入初始位置。

您應該使用CABasicAnimation來使用旋轉,您可以隨時停止保持最後的位置。使用

1

現有的代碼就可以實現它通過以下方式

var isTapped = true 

@IBAction func startStopButtonTapped(_ sender: Any) { 
    ruotate() 
    isTapped = !isTapped 
} 

func ruotate() { 
    if isTapped { 
     let rotationAnimation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") 
     rotationAnimation.toValue = NSNumber(value: Double.pi * 2.0) 
     rotationAnimation.duration = 1; 
     rotationAnimation.isCumulative = true; 
     rotationAnimation.repeatCount = HUGE; 
     self.imageWood?.layer.add(rotationAnimation, forKey: "rotationAnimation") 
    }else{ 
     self.imageWood?.layer.removeAnimation(forKey: "rotationAnimation") 
    } 
} 
1

蘋果增加了一個新的類,UIViewPropertyAnimator,到iOS 10. UIViewPropertyAnimator讓您輕鬆創建可暫停基於的UIView的動畫,扭轉,並來回擦洗。

如果您重構代碼以使用A UIViewPropertyAnimator,則應該可以暫停和恢復動畫。

我有一個sample project on Github演示使用UIViewPropertyAnimator。我建議看看這個。

+0

謝謝鄧肯。我期待支持iOS 9+,因此可能是目前的第二種選擇。 –

+0

另外,我發現你的圖書館雖然相當了不起,但有點複雜以適應我的項目。我不知道我會將旋轉邏輯實現到視圖控制器中。我明白有一個'viewAnimator',但並不是每個東西都會起作用。 –

+0

看到我的第二個答案。這表明如何停止動畫並使其凍結在當前狀態。 –

2

如果您使用UIView動畫,操作系統仍會創建一個或多個CAAnimation對象。因此,爲了阻止一個UIView動畫,你仍然可以使用:

myView.layer.removeAllAnimations() 

或者,如果您創建一個使用一個層上的CAAnimation動畫:

myLayer.removeAllAnimations() 

在這兩種情況下,你可以捕捉的當前狀態動畫並將其設置爲刪除動畫之前的最終狀態。如果你在一個視圖做動畫的變換,就像在這個問題上,該代碼可能是這樣的:

func stopAnimationForView(_ myView: UIView) { 

    //Get the current transform from the layer's presentation layer 
    //(The presentation layer has the state of the "in flight" animation) 
    let transform = myView.layer.presentationLayer.transform 

    //Set the layer's transform to the current state of the transform 
    //from the "in-flight" animation 
    myView.layer.transform = transform 

    //Now remove the animation 
    //and the view's layer will keep the current rotation 
    myView.layer.removeAllAnimations() 
} 

如果你動畫以外的變換你需要更改代碼的屬性以上。