Meilleures pratiques d'animation UIView sur iPhone

142

Quelle est la meilleure pratique pour animer les transitions de vue sur l'iPhone?

Par exemple, l' ViewTransitionsexemple de projet d'Apple utilise un code tel que:

CATransition *applicationLoadViewIn = [CATransition animation];
[applicationLoadViewIn setDuration:1];
[applicationLoadViewIn setType:kCATransitionReveal];
[applicationLoadViewIn setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
[[myview layer] addAnimation:applicationLoadViewIn forKey:kCATransitionReveal];

mais il y a aussi des extraits de code flottant sur le net qui ressemblent à ceci:

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:myview cache:YES];
[myview removeFromSuperview];
[UIView commitAnimations];

Quelle est la meilleure approche? Si vous pouviez également fournir un extrait, ce serait très apprécié.

REMARQUE: je n'ai pas pu faire fonctionner correctement la deuxième approche.

Keith Fitzgerald
la source

Réponses:

118

De la section de référence UIView sur la beginAnimations:context:méthode:

L'utilisation de cette méthode est déconseillée dans iPhone OS 4.0 et versions ultérieures. Vous devez utiliser les méthodes d'animation basées sur des blocs à la place.

Par exemple, d'une animation basée sur des blocs basée sur le commentaire de Tom

[UIView transitionWithView:mysuperview 
                  duration:0.75
                   options:UIViewAnimationTransitionFlipFromRight
                animations:^{ 
                    [myview removeFromSuperview]; 
                } 
                completion:nil];
Rafael Vega
la source
4
Donc ... pour être clair, cela signifie utiliser la première approche (CATransition), pas la seconde?
Steve N
2
Oui, c'est la première approche (CATransition).
NebulaFox
16
@Steven N, non, cela signifie plutôt utiliser les animations basées sur des blocs UIView. Ils sont essentiellement les mêmes que beginAnimationset friends, mais utilisent des fonctionnalités de blocage / fermeture.
Dan Rosenstark
36
Oui, Yar a raison. Voici à quoi ressemble une animation de bloc: [UIView transitionWithView:mysuperview duration:0.75 options:UIViewAnimationTransitionFlipFromRight animations:^{ [myview removeFromSuperview]; } completion:nil]Consultez la documentation UIView pour plus de détails.
Tom van Zummeren
3
Sauf si vous souhaitez prendre en charge les téléphones 3.1.3. Alors n'utilisez pas de blocs.
ZaBlanc
69

J'utilise ce dernier pour beaucoup de belles animations légères. Vous pouvez l'utiliser pour faire un fondu enchaîné de deux vues, ou en fondre une devant une autre, ou en fondre. Vous pouvez prendre une vue sur une autre comme une bannière, vous pouvez étirer ou rétrécir une vue ... Je reçois beaucoup de kilomètres avec beginAnimation/ commitAnimations.

Ne pensez pas que tout ce que vous pouvez faire est:

[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:myview cache:YES];

Voici un exemple:

[UIView beginAnimations:nil context:NULL]; {
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationDelegate:self];
    if (movingViewIn) {
// after the animation is over, call afterAnimationProceedWithGame
//  to start the game
        [UIView setAnimationDidStopSelector:@selector(afterAnimationProceedWithGame)];

//      [UIView setAnimationRepeatCount:5.0]; // don't forget you can repeat an animation
//      [UIView setAnimationDelay:0.50];
//      [UIView setAnimationRepeatAutoreverses:YES];

        gameView.alpha = 1.0;
        topGameView.alpha = 1.0;
        viewrect1.origin.y = selfrect.size.height - (viewrect1.size.height);
        viewrect2.origin.y = -20;

        topGameView.alpha = 1.0;
    }
    else {
    // call putBackStatusBar after animation to restore the state after this animation
        [UIView setAnimationDidStopSelector:@selector(putBackStatusBar)];
        gameView.alpha = 0.0;
        topGameView.alpha = 0.0;
    }
    [gameView setFrame:viewrect1];
    [topGameView setFrame:viewrect2];

} [UIView commitAnimations];

Comme vous pouvez le voir, vous pouvez jouer avec l'alpha, les images et même les tailles d'une vue. S'amuser. Vous serez peut-être surpris par ses capacités.

Mahboudz
la source
52

La différence semble être la quantité de contrôle dont vous avez besoin sur l'animation.

L' CATransitionapproche vous donne plus de contrôle et donc plus de choses à mettre en place, par exemple. la fonction de chronométrage. En tant qu'objet, vous pouvez le stocker pour plus tard, refactoriser pour pointer toutes vos animations dessus pour réduire le code dupliqué, etc.

Les UIViewméthodes de classe sont des méthodes pratiques pour les animations courantes, mais sont plus limitées que CATransition. Par exemple, il n'y a que quatre types de transition possibles (retournement à gauche, retournement à droite, boucle vers le haut, boucle vers le bas). Si vous vouliez faire un fondu d'entrée, vous devrez soit creuser pour CATransition'sfondre la transition, soit mettre en place une animation explicite de votre UIViewalpha.

Notez que CATransitionsur Mac OS X vous permettra de spécifier un CoreImagefiltre arbitraire à utiliser comme transition, mais dans l'état actuel des choses, vous ne pouvez pas le faire sur l'iPhone, ce qui manque CoreImage.

Ryan McCuaig
la source
7
Notez qu'il s'agit d'un conseil de l'ère iOS 2.0. Voir la réponse de Rafael Vega sur les méthodes basées sur les blocs si vous êtes sur iOS 4.0 ou supérieur.
Ryan McCuaig
Notez également que CoreImage est désormais disponible à partir d'iOS 5, mais seulement quelques-unes de ses fonctionnalités. Je pense que vous pouvez utiliser une transition CoreImage dans une animation, mais vous ne pouvez pas créer de filtres CoreImage personnalisés sur iOS (5).
Aaron Ash
26

Nous pouvons animer des images dans iOS 5 en utilisant ce code simple.

CGRect imageFrame = imageView.frame;
imageFrame.origin.y = self.view.bounds.size.height;

[UIView animateWithDuration:0.5
    delay:1.0
    options: UIViewAnimationCurveEaseOut
    animations:^{
        imageView.frame = imageFrame;
    } 
    completion:^(BOOL finished){
        NSLog(@"Done!");
    }];
Gourou
la source
5
ceci est également disponible dans iOS 4 et est appelé animation "basée sur des blocs". Il n'est pas limité à iOS 5 et versions ultérieures.
johnbakers
8

Dans la UIViewdocumentation, lisez cette fonction pour ios4 +

+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion
Chris
la source
6

Quoi qu'il en soit, la méthode "Block" est préférée de nos jours. Je vais expliquer le bloc simple ci-dessous.

Considérez le coupé ci-dessous. bug2 et bug 3 sont des imagesViews. L'animation ci-dessous décrit une animation d'une durée de 1 seconde après un délai de 1 seconde. Le bug3 est déplacé de son centre vers le centre de bug2. Une fois l'animation terminée, elle sera enregistrée "Center Animation Done!".

-(void)centerAnimation:(id)sender
{
NSLog(@"Center animation triggered!");
CGPoint bug2Center = bug2.center;

[UIView animateWithDuration:1
                      delay:1.0
                    options: UIViewAnimationCurveEaseOut
                 animations:^{
                     bug3.center = bug2Center;
                 } 
                 completion:^(BOOL finished){
                     NSLog(@"Center Animation Done!");
                 }];
}

J'espère que c'est propre !!!

Deepukjayan
la source
2
vous avez assigné le CGPoint bug3.center à bug3Center et juste après cela vous affectez le CGPoint bug2.center à la même variable bug3Center? Pourquoi fais-tu ça ?
pnizzle
oups !! c'est une typo copains. Mis à jour maintenant.
Deepukjayan
2

Voici le code pour une animation fluide, qui pourrait être utile pour de nombreux développeurs.
J'ai trouvé cet extrait de code de ce tutoriel.

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[animation setAutoreverses:YES];
[animation setFromValue:[NSNumber numberWithFloat:1.3f]];
[animation setToValue:[NSNumber numberWithFloat:1.f]];
[animation setDuration:2.f];
[animation setRemovedOnCompletion:NO];

[animation setFillMode:kCAFillModeForwards];
[[self.myView layer] addAnimation:animation forKey:@"scale"];/// add here any Controller that you want t put Smooth animation.
iPatel
la source
2

essayons de vérifier pour Swift 3 ...

UIView.transition(with: mysuperview, duration: 0.75, options:UIViewAnimationOptions.transitionFlipFromRight , animations: {
    myview.removeFromSuperview()
}, completion: nil)
Saurabh Sharma
la source