2010-02-21 89 views
43

我有一個iPhone的基本旋轉動畫。有什麼辦法可以「暫停」動畫,以保持視圖的位置?我想這樣做的一種方式是導致動畫「完成」而不是調用「刪除」它,我將如何做到這一點?有沒有辦法暫停CABasicAnimation?

CABasicAnimation* rotationAnimation; 
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2]; 
rotationAnimation.duration = 100; 
rotationAnimation.cumulative = YES; 
rotationAnimation.repeatCount = HUGE_VALF; 
rotationAnimation.removedOnCompletion = NO; 
rotationAnimation.fillMode = kCAFillModeForwards; 
[myView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 

回答

143

最近出現了蘋果公司的技術說明QA1673介紹如何暫停/恢復層的動畫。

暫停和恢復動畫清單如下:

-(void)pauseLayer:(CALayer*)layer 
{ 
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; 
    layer.speed = 0.0; 
    layer.timeOffset = pausedTime; 
} 

-(void)resumeLayer:(CALayer*)layer 
{ 
    CFTimeInterval pausedTime = [layer timeOffset]; 
    layer.speed = 1.0; 
    layer.timeOffset = 0.0; 
    layer.beginTime = 0.0; 
    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime; 
    layer.beginTime = timeSincePause; 
} 

編輯: iOS版10引入了新的API - UIViewPropertyAnimator,允許更多的交互處理的動畫,例如它使易於暫停和恢復動畫或'尋求'它到一些特定的進展價值。

+0

這對我來說工作得很好,但是當我處於暫停狀態,並且旋轉我的設備時,我失去了與應用程序交互的所有能力。它實際上並沒有墜毀,但它看起來「凍結」。是否與「willAnimateRotationToInterfaceOrientation」有衝突? – YoCoh

+0

@YoCoh,它確實可以暫停視圖的標準旋轉動畫,並且在動畫過程中,用戶交互可能被禁用(可能是這種情況),標準動畫並沒有完成,最終導致UI停留在禁用狀態。不知道如何解決方法 – Vladimir

+0

http://ronnqvi.st/controlling-animation-timing/解釋此代碼的工作原理 –

6

設置你的視圖的匹配presentationLayer的狀態層的當前狀態,然後刪除動畫:

CALayer *pLayer = [myView.layer presentationLayer]; 
myView.layer.transform = pLayer.transform; 
[myView.layer removeAnimationForKey:@"rotationAnimation"]; 
+4

雖然這節省了位置,它不作爲當我將動畫重新添加到視圖時,視圖移動速度略慢,以適應更短的距離等量的時間。是否還需要採取其他措施來恢復停止播放的動畫? – mclaughlinj

0

您可以使用定時器或處理動畫的委託方法:

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag 

這裏是我的代碼:

// ... 
[self startAnimation]; 
// ... 

- (void)startAnimation { 
CABasicAnimation* rotationAnimation; 
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
rotationAnimation.fromValue = [NSNumber numberWithFloat:0]; 
rotationAnimation.toValue = [NSNumber numberWithFloat: M_2_PI]; 
rotationAnimation.duration = 1.0; 
rotationAnimation.cumulative = YES; 
// rotationAnimation.repeatCount = 0; // <- if repeatCount set to infinite, we'll not receive the animationDidStop notification when the animation is repeating 
rotationAnimation.removedOnCompletion = NO; 
rotationAnimation.fillMode = kCAFillModeForwards; 
rotationAnimation.delegate = self; // <- hanlde the animationDidStop method 
[myView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 

} 

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { 
if (shouldContinueAnimation) // <- set a flag to start/stop the animation 
    [self startAnimation]; 
} 

希望它可以幫助你。

+4

注意!這不是推薦的方式,除非你有特殊需要這樣做。想象一下你有一個無限的運行動畫。當我們在應用程序進入背景之前暫停動畫,然後嘗試在它進入前景時恢復它時,此方法將無濟於事。 – Anshu

0

簡單的一個

self.viewBall.layer.position = self.viewBall.layer.presentationLayer().position 
7

答案對於斯威夫特3:

現金@Vladimir

代碼:

func pauseAnimation(){ 
    var pausedTime = layer.convertTime(CACurrentMediaTime(), fromLayer: nil) 
    layer.speed = 0.0 
    layer.timeOffset = pausedTime 
} 

func resumeAnimation(){ 
    var pausedTime = layer.timeOffset 
    layer.speed = 1.0 
    layer.timeOffset = 0.0 
    layer.beginTime = 0.0 
    let timeSincePause = layer.convertTime(CACurrentMediaTime(), fromLayer: nil) - pausedTime 
    layer.beginTime = timeSincePause 
} 
相關問題