2015-10-15 1 views
1

J'ai un CAShapeLayer où j'anime un cercle. L'animation consiste d'abord à "dessiner" le cercle dans le sens des aiguilles d'une montre puis à redessiner le cercle dans le sens des aiguilles d'une montre. Sort d'un "cercle tournant". Une autre façon de le mettre: Déplacez le point de fin de course du chemin pour commencer, puis déplacez le point de départ jusqu'à la fin.Glitches lors de la mise en file d'attente CAAnimations

L'animation elle-même fonctionne, mais elle produit des problèmes de temps en temps. Il se manifeste par un bref aperçu du cercle entier lorsqu'il est supposé être "non tiré".

Pourquoi cela se produit-il et comment pouvez-vous le réparer?

Merci,

// Shape creation 
layer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, self.width - 2 * OUTER_BORDER_WIDTH, self.width - 2* OUTER_BORDER_WIDTH)].CGPath; 

// Animation queuing 
-(void) applyNextAnimation 
{ 

    CABasicAnimation* animation; 

    if (self.animatingOpening) 
    { 
     animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 
     animation.fromValue = [NSNumber numberWithFloat:0.0f]; 
     animation.toValue = [NSNumber numberWithFloat:1.0f]; 
     self.animatingOpening = NO; 
    } 
    else 
    { 
    animation = [CABasicAnimation animationWithKeyPath:@"strokeStart"]; 
     animation.fromValue = [NSNumber numberWithFloat:0.0f]; 
     animation.toValue = [NSNumber numberWithFloat:1.0f]; 
     self.animatingOpening = YES; 
    } 

    animation.duration = 1.0f; 
    animation.autoreverses = NO; 
    animation.delegate = self; 
    animation.removedOnCompletion = YES; 
    [self.outerCircleLayer addAnimation:animation forKey:@"stroke"]; 
} 

// Animation stop callback 
-(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag 
{ 
    if (self.isAnimating) 
    { 
     [self applyNextAnimation]; 
    } 
} 

Répondre

1

Il clignote becuase vous ne définissez pas la propriété correspondante sur la couche. Ainsi, lorsque l'animation est terminée, le modèle de la couche est toujours dans l'état pré-animé et c'est ce que vous voyez momentanément entre les deux animations.

Cela vous obtenir vers ce que vous voulez ...

if (self.animatingOpening) 
{ 

    self.outerCircleLayer.strokeStart = 0.0; 

    animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 
    animation.fromValue = [NSNumber numberWithFloat:0.0f]; 
    animation.toValue = [NSNumber numberWithFloat:1.0f]; 
    self.animatingOpening = NO; 
} 
else 
{ 
    self.outerCircleLayer.strokeStart = 1.0; 

    animation = [CABasicAnimation animationWithKeyPath:@"strokeStart"]; 
    animation.fromValue = [NSNumber numberWithFloat:0.0f]; 
    animation.toValue = [NSNumber numberWithFloat:1.0f]; 
    self.animatingOpening = YES; 
} 

animation.duration = 1.0f; 
animation.autoreverses = NO; 

qui fonctionne presque, mais vous remarquerez un petit problème plus subtil que vous passer de l'état de commencer à animer non tiré de l'état de dessin. Le début du cercle a une petite animation inverse au démarrage. Ceci est une animation implicite déclenchée par la définition de strokeStart de 1.0 à 0.0: dont vous devez vous débarrasser pour que tous les effets d'animation soient sous votre contrôle. Vous pouvez obtenir simplement que la plupart en mettant disableActions YES sur CATransaction:

[CATransaction setDisableActions:YES]; 

(ajoutez juste au-dessus if (self.animatingOpening))

+0

Excellent! J'ai ajouté '[CATransaction setDisableActions: NO];' à la fin de l'instruction if-else pour conserver une animation non montrée ici. (Une autre couche) –

+1

Heureux que c'était utile. Je vois que vous avez affaire à des problèmes intéressants impliquant le stockage de données de capteurs à haute fréquence, donc j'ai ajouté quelques réflexions à l'une de vos autres questions .. – foundry