2010-12-10 34 views
0

J'ai vu un code qui supprime une couche donnée à partir de son surcouche en procédant comme suit:La portée d'un bloc CATransaction

void RemoveImmediately(CALayer *layer) { 
    [CATransaction flush]; 
    [CATransaction begin]; 
    [CATransaction setValue:(id)kCFBooleanTrue 
        forKey:kCATransactionDisableActions]; 
    [layer removeFromSuperlayer]; 
    [CATransaction commit]; 
} 

J'ai écrit une méthode qui modifie la position d'une couche donnée dans une animation façon d'utiliser CAKeyframeAnimation, qui ressemble à ceci:

- (void)animateMovingObject:(NXUIObject*)obj 
      fromPosition:(CGPoint)startPosition 
      toPosition:(CGPoint)endPosition 
       duration:(NSTimeInterval)duration {  

    CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 
    pathAnimation.calculationMode = kCAAnimationPaced; 
    pathAnimation.duration = duration; 

    CGMutablePathRef curvedPath = CGPathCreateMutable(); 
    CGPathMoveToPoint(curvedPath, NULL, startPosition.x, startPosition.y); 
    CGPathAddCurveToPoint(curvedPath, NULL, 
         startPosition.x, endPosition.y, 
         startPosition.x, endPosition.y, 
         endPosition.x, endPosition.y); 
    pathAnimation.path = curvedPath; 
    [obj addAnimation:pathAnimation forKey:@"pathAnimation"]; 
    CGPathRelease(curvedPath); 
} 

Pour tout savoir, tout va bien. Supposons maintenant que j'ai dans mon application une «couche maîtresse», qui a 3 sous-couches. Je veux que les deux premières sous-couches soient déplacées vers une autre position et que la dernière soit supprimée. Donc, je l'ai fait ce qui suit:

CALayer obj1 = ... // set up layer and add as sublayer 
[self.masterLayer addSublayer:obj1]; 
[self animateMovingObject:obj1 
      fromPosition:CGPointMake(0.0, 0.0) 
       toPosition:CGPointMake(100.0, 100.0) 
       duration:2.0]; 

CALayer obj2 = ... // set up layer and add as sublayer 
[self.masterLayer addSublayer:obj2]; 
[self animateMovingObject:obj2 
      fromPosition:CGPointMake(0.0, 0.0) 
       toPosition:CGPointMake(150.0, 100.0) 
       duration:2.0]; 

CALayer obj3 = ... // set up layer and add as sublayer 
[self.masterLayer addSublayer:obj3]; 
// ... 
RemoveImmediately(obj3);  // This removes the two previous animations too 
//[obj3 removeFromSuperlayer]; // This just removes obj3, the previous animations works 

Notez que si je l'appelle RemoveImmediately(), en passant même obj3 comme argument, je ne vois pas les deux premières couches étant animés. Toutefois, si je supprime le obj3 en appelant simplement removeFromSuperlayer, les deux premières couches sont animées normalement. On dirait que le bloc CATransaction annule toutes les animations en cours, même celles qui ont été créées avec CAKeyframeAnimation.

Qu'est-ce qu'il me manque?

Merci D'avance.

Répondre

2

La portée d'un CATransaction devrait juste être entre les lignes [CATransaction begin] et [CATransaction commit].

De même, vous ne devriez pas avoir besoin de [CATransaction flush] dans ce code. Apple recommande généralement de ne pas forcer l'exécution des transactions en attente pour des raisons de performances, et la transaction que vous y configurez ne devrait pas affecter les animations en attente.

Je suppose que ce comportement étrange est toujours lié à ce que vous avez demandé dans votre previous question, où les trois animations interfèrent d'une manière ou d'une autre. Comme je l'ai commenté ici, cela se comporte comme si les trois animations étaient ajoutées à une couche, et non à trois indépendantes. Je vérifiais et m'assurais qu'il n'y avait aucune possibilité que cela se produise (pointeurs croisés, etc.).

+0

Merci, je me suis montré le moyen de faire avancer les choses! Le problème était la méthode «flush». Je l'ai enlevé et maintenant je peux voir toutes les animations fonctionnant normalement. La seule chose que 'obj1', 'obj2' et 'obj3' ont en commun est qu'ils sont des sous-couches de 'masterLayer', donc il n'y avait pas de pointeurs croisés ou d'animation interférant dans un autre. En appelant la méthode 'flush', les animations précédentes ont été arrêtées (l'argument 'animationDidStop: finished:' de la méthode déléguée a renvoyé NO, indiquant qu'elles ont été arrêtées manuellement (ce qui est arrivé lorsque la méthode 'flush' a été appelée)). –

+0

Bien que cela a fonctionné, j'ai essayé de comprendre ce que la documentation dit à propos de la méthode flush (http://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CATransaction_class/Introduction/Introduction.html#//apple_ref/ occ/clm/CATransaction/flush) et je ne comprends toujours pas pourquoi cela provoque l'arrêt de mes animations explicites. –

+0

@Eduardo - Oui, j'ai aussi eu des problèmes avec les animations '[CATransaction flush]' qui perturbent les animations, car elles interfèrent avec le pipeline normal de rendu de l'animation Core. Une seule fois j'en avais besoin pour quelque chose, et même alors j'ai trouvé un moyen de refaire ce que je faisais pour finalement supprimer cet appel. –