C’è un modo per mettere in pausa un CABasicAnimation?

Ho un’animazione di base di rotazione dell’iPhone. C’è un modo in cui posso “mettere in pausa” l’animazione in modo che la posizione della vista venga mantenuta? Immagino che un modo per farlo sarebbe quello di far “completare” l’animazione invece di chiamare “rimuovere” su di essa, come potrei farlo?

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

Apparsa di recente la nota tecnica di Apple QA1673 descrive come mettere in pausa / riprendere l’animazione del livello.

Metti in pausa e riprendi la lista delle animazioni è qui sotto:

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

Modifica: iOS 10 ha introdotto una nuova API – UIViewPropertyAnimator che consente di gestire le animazioni in modo più interattivo, ad esempio rende facile mettere in pausa e riprendere l’animazione o “cercarla” su un particolare valore di avanzamento.

Risposta per Swift 3:

Crediti @ Vladimir

Codice:

  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 } 

Imposta lo stato corrente del livello della vista in modo che corrisponda allo stato di presentationLayer , quindi rimuovi l’animazione:

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

Puoi utilizzare un timer o gestire il metodo dei delegati di animazione:

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

Ecco il mio codice:

 // ... [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]; } 

Spero possa aiutarti.

Quello più semplice

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