2010-02-21 22 views
43

J'ai une animation de base de l'iPhone. Est-il possible que je puisse "mettre en pause" l'animation afin que la position de la vue soit maintenue? Je suppose qu'une manière de faire ceci serait de faire "compléter" l'animation au lieu d'appeler "supprimer" dessus, comment ferais-je cela?Existe-t-il un moyen de suspendre une 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"]; 

Répondre

143

Récemment apparu note technique d'Apple QA1673 décrit comment mettre en pause l'animation/CV couche.

Pause et reprendre des animations liste est ci-dessous:

-(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 introduit une nouvelle API - UIViewPropertyAnimator qui permet de gérer des animations plus interactive, par exemple, il rend facile de faire une pause et de reprendre l'animation ou "chercher" à une certaine valeur de progrès.

+0

Cela fonctionne très bien pour moi, cependant, quand je suis dans un état en pause, et faire pivoter mon appareil, je perds toute capacité à interagir avec l'application. Il n'a pas réellement planté, mais il semble "gelé". Y a-t-il un conflit possible avec "willAnimateRotationToInterfaceOrientation"? – YoCoh

+0

@YoCoh, il peut effectivement mettre en pause aussi des animations de rotation standard pour une vue, et comme pendant les animations l'interaction utilisateur peut être désactivée (c'est probablement le cas) et l'animation standard ne se termine pas avec l'UI bloquée. pas sûr comment contourner le problème – Vladimir

+0

http://ronnqvi.st/controlling-animation-timing/ explique comment ce code fonctionne –

6

Définir l'état actuel de la couche de vue pour correspondre à l'état de la presentationLayer, puis retirez l'animation:

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

Bien que cela sauve la position, il ne sert pas point de départ lorsque je rajoute l'animation à la vue, la vue se déplace légèrement plus lentement pour s'adapter à la distance la plus courte La même quantité de temps. Y a-t-il une autre étape à franchir pour pouvoir reprendre l'animation là où elle s'était arrêtée? – mclaughlinj

0

Vous pouvez utiliser une minuterie ou gérer la méthode déléguée d'animation:

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

Voici mon code:

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

L'espoir peut vous aider.

+4

ATTENTION !!! Ce n'est pas la façon recommandée de le faire, sauf si vous avez un besoin spécial de le faire de cette façon. Imaginez que vous avez une animation de course infinie. Cette méthode n'aidera pas lorsque nous suspendons l'animation avant que l'application n'entre en arrière-plan, puis que nous essayons de la reprendre quand elle entre au premier plan. – Anshu

0

plus simple

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

Réponse Swift 3:

Crédits @Vladimir

code:

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 
}