2010-02-21 86 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 
} 
相关问题