Meilleure façon d'effectuer plusieurs animations UIView séquentielles?
J'ai une série de 8 UIView animations qui se produisent directement après mon point de vue est chargé. Maintenant, je suis à l'accomplissement de cette aide de la animationDidStop:finished:context
délégué de la méthode, et tout fonctionne comme prévu. Le problème est que j'ai une nouvelle méthode pour chaque animation. La plupart du code de chacune de ces méthodes est répété, avec seulement de l'animation de la durée et le positionnement réel des éléments changeant.
J'ai essayé de créer une méthode unique qui serait appelé et ont le contexte de tenir les paramètres nécessaires pour modifier l'INTERFACE utilisateur de manière appropriée, mais il semble être de manière récursive s'appelant elle-même bien au-delà de la quantité de fois que je l'appelle:
-(void)animationDidStop:(NSString *)animationID finished:(BOOL)finished context:(void *)context{
NSNumber *number = (NSNumber *)context;
int animationStep = [number intValue];
int nextAnimationStep = animationStep + 1;
NSNumber *nextAnimationStepNumber = [NSNumber numberWithInt:nextAnimationStep];
NSLog(@"Animation Step: %i", animationStep);
CGRect firstFrame = CGRectMake(self.feedsScroll.frame.size.width * 2, 0.0f, self.secondFeedView.view.frame.size.width, self.secondFeedView.view.frame.size.height);
CGRect thirdFrame = CGRectMake(self.feedsScroll.frame.size.width * 2, 0.0f, self.thirdFeedView.view.frame.size.width, self.thirdFeedView.view.frame.size.height);
[UIView beginAnimations:nil context:nextAnimationStepNumber];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDelegate:self];
if (animationStep < 8)
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
NSLog(@"Beginning animations");
switch (animationStep) {
case 0:
[UIView setAnimationDuration:.3];
self.firstFeedView.view.center = CGPointMake(self.firstFeedView.view.center.x + 30, self.firstFeedView.view.center.y);
break;
case 1:
[UIView setAnimationDuration:.3];
self.firstFeedView.view.center = CGPointMake(self.firstFeedView.view.center.x - 30, self.firstFeedView.view.center.y);
break;
case 2:
[UIView setAnimationDuration:.3];
[self.secondFeedView.view setFrame:firstFrame];
break;
case 3:
[UIView setAnimationDuration:.3];
self.secondFeedView.view.center = CGPointMake(self.secondFeedView.view.center.x + 30, self.firstFeedView.view.center.y);
break;
case 4:
[UIView setAnimationDuration:.3];
self.secondFeedView.view.center = CGPointMake(self.secondFeedView.view.center.x - 30, self.firstFeedView.view.center.y);
break;
case 5:
NSLog(@"Animation step 6");
[UIView setAnimationDuration:.5];
self.firstFeedView.view.center = CGPointMake(self.firstFeedView.view.center.x - 230, self.firstFeedView.view.center.y);
self.secondFeedView.view.center = CGPointMake(self.secondFeedView.view.center.x - 230, self.firstFeedView.view.center.y);
break;
case 6:
[UIView setAnimationDuration:.5];
[self.thirdFeedView.view setFrame:thirdFrame];
break;
case 7:
[UIView setAnimationDuration:.3];
self.thirdFeedView.view.center = CGPointMake(self.thirdFeedView.view.center.x + 30, self.firstFeedView.view.center.y);
break;
case 8:
[UIView setAnimationDuration:.3];
self.thirdFeedView.view.center = CGPointMake(self.thirdFeedView.view.center.x - 30, self.thirdFeedView.view.center.y);
break;
default:
break;
}
[UIView commitAnimations];
}
Je sais que c'est probablement une implémentation naïve. Je suis nouveau sur le développement iPhone, et suis à la recherche de quelques bonnes pratiques à appliquer ici. Vais-je à ce sujet dans le mauvais sens?
source d'informationauteur Mark Struzinski
Vous devez vous connecter pour publier un commentaire.
Si vous êtes prêt à passer à l'iOS 4.0, les nouveaux blocs d'animation approche peut rendre cette animation chaînage trivial. Par exemple:
va provoquer
view
à animer (0, 0) sur une durée de 1 seconde, le fondu de 0,2 secondes, puis être retiré de son superview. Ces animations seront séquentielle.Le premier bloc dans la
+animateWithDuration:animations:completion:
méthode de classe contient les modifications de propriétés à animer à la fois, et la deuxième est que l'action soit exécutée à la fin de l'animation. Parce que ce rappel peut contenir une autre animation de ce genre, vous pouvez imbriquer pour créer arbitraire des chaînes d'animations.Vous pouvez utiliser les blocs pour ce but et d'obtenir un bon résultat.
Prises à partir de: http://xibxor.com/objective-c/uiview-animation-without-nested-hell/
Nous avons créé un composant pour le chaînage de l'animation étapes de façon déclarative à l'aide de blocs (CPAnimationSequence sur Github). Nous avons décrit les motivations et les raisons qui le dans notre le développement d'iOS blog.
Il vous donne très lisible le code, quelque chose comme ceci:
Le "contexte" est un void*, et, par conséquent, ne sont pas conservés. Il ya quelques options:
id
).int animationStep = [animationID intValue];
et[UIView beginAnimations:[NSString stringWithFormat:@"%d", nextAnimationStep] context:NULL];
. Cela se sent aussi dégueulasse.int animationStep = (int)context;
et[UIView beginAnimations:nil context:(void*)nextAnimationStep];
. C'est dégueulasse (et probablement la cause de comportements indéfinis selon la norme C).Sur une autre note,
finished:(BOOL)finished
devrait êtrefinished:(NSNumber*)finished
. Ils ont fait une erreur dans l'original des documents; c'était sans doute plus facile de changer les docs afin de refléter l'API au lieu de changer l'API et d'avoir, par magie, d'assurer la rétrocompatibilité (même si le passage d'un bool est plus sensible).mettre cela dans le ViewDidLoad