有没有办法暂停CABasicAnimation?

时间:2010-02-21 18:20:05

标签: iphone core-animation cabasicanimation

我有一个iPhone的基本旋转动画。有什么方法可以“暂停”动画,以便保持视图的位置?我想这样做的一种方法是让动画“完成”而不是在其上调用“删除”,我该怎么做?

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"];

6 个答案:

答案 0 :(得分:150)

最近出现的Apple技术说明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,允许更加交互式地处理动画,例如,它可以轻松地暂停和恢复动画或“寻找”某些特定的进度值。

答案 1 :(得分:11)

回答Swift 3:

Credits @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
}

答案 2 :(得分:6)

设置视图图层的当前状态以匹配presentationLayer的状态,然后删除动画:

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

答案 3 :(得分:1)

@Vladimir和@ Supratik-Majumdar的信用

将Swift 5.1作为CALayer扩展

extension CALayer
{
    func pauseAnimation() {
        if isPaused() == false {
            let pausedTime = convertTime(CACurrentMediaTime(), from: nil)
            speed = 0.0
            timeOffset = pausedTime
        }
    }

    func resumeAnimation() {
        if isPaused() {
            let pausedTime = timeOffset
            speed = 1.0
            timeOffset = 0.0
            let timeSincePause = convertTime(CACurrentMediaTime(), from: nil) - pausedTime
            beginTime = timeSincePause
        }
    }

    func isPaused() -> Bool {
        return speed == 0
    }
}

答案 4 :(得分: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];
}

希望它可以帮到你。

答案 5 :(得分:-1)

最简单的一个

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