Есть ли способ приостановить CABasicAnimation? - PullRequest
45 голосов
/ 21 февраля 2010

У меня есть базовая анимация вращения 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"];

Ответы [ 5 ]

150 голосов
/ 09 июня 2010

Недавно появившаяся техническая заметка 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;
}

Edit: В iOS 10 появился новый API - UIViewPropertyAnimator, который позволяет более интерактивно обрабатывать анимации, например, позволяет легко приостанавливать и возобновлять анимацию или «искать» ее для определенного значения прогресса.

12 голосов
/ 03 ноября 2016

Ответ за Свифт 3:

Кредиты @ Владимир

Код:

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

func resumeAnimation(){
  let 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
}
6 голосов
/ 23 февраля 2010

Установите текущее состояние слоя вашего представления в соответствии с состоянием presentationLayer, затем удалите анимацию:

CALayer *pLayer = [myView.layer presentationLayer];
myView.layer.transform = pLayer.transform;
[myView.layer removeAnimationForKey:@"rotationAnimation"];
0 голосов
/ 29 мая 2015

Простейший

self.viewBall.layer.position = self.viewBall.layer.presentationLayer().position
0 голосов
/ 12 декабря 2011

Вы можете использовать таймер или обработать метод делегата анимации:

- (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];
}

Надеюсь, это поможет вам.

...