34 votes

Chaînage d'animations de base

Qui est le plus élégant et modulaire de la chaîne d'animation au Cœur de l'Animation du contexte?

Je veux faire des animations qui commence juste au moment où à un autre (par exemple, en changeant position puis opacity).. normale approche consiste à modifier directement les propriétés:

layer.position = new_point;
layer.opacity = 0.0f;

mais cela va faire en même temps. Je veux attendre que l'autre..

Et ce à propos de l'enchaînement des animations pour les différents objets? J'ai lu sur CATransaction utilisé comme:

[CATransaction begin]
layer1.property = new_property;
[CATransaction begin]
layer2.property2 = new_property2;
[CATransaction commit];
[CATransaction commit];

mais il ne semble pas fonctionner..

76voto

Matt Long Points 16701

Vous pouvez également utiliser le groupement d'animations et utiliser le champ beginTime de l'animation. Essayez quelque chose comme ça:

 CABasicAnimation *posAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
[posAnimation setFromValue:[NSNumber numberWithFloat:0.0]];
[posAnimation setToValue:[NSNumber numberWithFloat:1.0]];
// Here's the important part
[posAnimation setDuration:10.0];
[posAnimation setBeginTime:0.0];

CABasicAnimation *borderWidthAnimation = [CABasicAnimation animationWithKeyPath:@"borderWidth"];
[borderWidthAnimation setFromValue:[NSNumber numberWithFloat:0.0]];
[borderWidthAnimation setToValue:[NSNumber numberWithFloat:1.0]];
// Here's the important part
[borderWidthAnimation setDuration:10.0];
[borderWidthAnimation setBeginTime:5.0];

CAAnimationGroup *group = [CAAnimationGroup animation];
[group setDuration:10.0];
[group setAnimations:[NSArray arrayWithObjects:posAnimation, borderWidthAnimation, nil]];

[layer addAnimation:group forKey:nil];
 

Notez que la durée de l'animation entière est de 10 secondes. Le premier commence à la deuxième 0 et la seconde à 5 secondes.

5voto

Duncan C Points 18661

Comme Matt l'a souligné, vous pouvez créer une animation de groupes qui se composent de différentes animations pour la même couche avec différents temps de commencer. Vous pouvez également définir un délégué pour stand-alone CAAnimation objets ou CAAnimation Groupes et que chaque animation finitions il va appeler une animationDidStop:fini: méthode du délégué (à noter que les animations qui font partie d'un groupe de ne pas faire appel à leur délégué animationDidStop:fini: méthode.

J'ai pensé à un truc génial qui rend l'utilisation de la CAAnimation animationDidStop:fini: méthode de plus en plus puissants. J'utilise la méthode setValue:forKey: pour ajouter un bloc de code à un stand-alone de l'animation ou de l'animation de groupe, avec à la clé @"animationCompletionBlock". Je puis écrire un général animationDidStop:fini: méthode qui vérifie le tout complété l'animation d'un @"animationCompletionBlock" de la clé, et s'il le trouve, l'exécution du bloc de code.

Jetez un oeil à ce projet sur github pour un exemple de cette technique:

CAAnimation démo avec l'achèvement des blocs

Vous pouvez également Définir un groupe de animations à l'intérieur d'un

[CATransaction begin];
//...
[[CATransaction commit];

bloc, comme vous l'avez suggéré. Lorsque vous faites cela, vous pouvez utiliser le CATransaction méthode de classe setCompletionBlock: pour appeler un bloc de code lorsque toutes les animations dans la transaction en cours en groupe complet. L'achèvement de bloc pour une transaction peut alors déclencher la prochaine transaction.

0voto

Meltemi Points 11116

Je ne crois pas que vous puissiez "imbriquer" des animations de CA comme dans votre exemple.

Vous devez spécifier un délégué pour l'animation et placer votre deuxième "transition" dans le sélecteur animationDidStop:finished: du délégué.

Vous voudrez peut-être jeter un coup d’œil au Guide de programmation des types d’animation et du minutage d’ Apple.

0voto

Ahti Points 709

Ce que j'ai toujours préféré le réglage du départ et de fin de chaque animation séparément est ceci:

J'ai utilisé A2DynamicDelegate (dont le développement est en train de se passer dans le BlocksKit-Repo, qui sait pourquoi <_<) pour mettre en œuvre un completionBlock propriété dans une Catégorie sur CAAnimation.

Cela m'a permis de faire des trucs comme ça:

CAAnimation *a = ...
CAAnimation *b = ...
CAAnimation *c = ...

a.completionHandler = ^{
    [self.layer addAnimation:b forKey:@"foo"];
    [self.layer addAnimation:c forKey:@"bar"];
};

Beaucoup plus souple :)

J'ai téléchargé mon code pour le gestionnaire d'achèvement ici. Jetez un oeil à l'avis dans le fichier d'en-tête si. Je suis vraiment confus pourquoi la méthode n'est pas appelée.

-1voto

alex gray Points 5089

Sans y compris tous les "trucs" de mon "toolchain", cet exemple n'est pas directement copier/pastable... mais cela montre VRAIMENT facile de la stratégie pour "enchaînés" animations..

CATransform3D trans = m34();  // define chain-wide constants.
// Name your "stack". My "nextObject" returns arr[i]->done == nil. 
NSArray *layerStack = layer.sublayers;
//define a block, that "takes" a layer as it's argument.
void(^__block ChainBlock)(CALayer*) = ^(CALayer *m) { 
// animations, transforms, etc for each inividual "step".
    [m animate:@"transform" 
          // These are just NSValue-wrapped CAT3D's
          from:AZV3d(CATransform3DRotate(trans,  0,1,0,0)) 
            to:AZV3d(CATransform3DRotate(trans,1.5,1,0,0)) 
          time:2    // total time == each step * layerStack.count
         eased:kCAMediaTimingFunctionEaseOut
    completion:^{   // In completion, look for "next" layer.
                    CAL*  m2 = [layers nextObject]; 
// If there is "another" layer, call this block, again... with it.
                      if (m2)  chainAnis(m2);
// Otherise,you're done.  Cleanup, toggle values, whatevs.
                     else self.finishedProperty = YES;
    }];
};
// Give the block we just defined your "first" layer.
ChainBlock(layerStack[0]);  // It will recursively feed itself.

Ceci dépend évidemment de certains "externe de la magie", mais le concept est simple, et élimine (grâce à des dépendances) la nécessité de "faire face à" TOUTE sorte de brute délégation. En particulier, l' animate:from:to:time:easing:completion, etc. catégories viennent de la grande FunSize Cadre, sur Github.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X