iPhone UIView Animación Mejores prácticas

142

¿Qué se considera la mejor práctica para animar las transiciones de vista en el iPhone?

Por ejemplo, el ViewTransitionsproyecto de muestra de apple usa código como:

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

pero también hay fragmentos de código flotando alrededor de la red que se ven así:

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

¿Cuál es el mejor enfoque? Si pudieras proporcionar un fragmento también sería muy apreciado.

NOTA: No he podido lograr que el segundo enfoque funcione correctamente.

Keith Fitzgerald
fuente

Respuestas:

118

De la sección de referencia de UIView sobre el beginAnimations:context:método:

Se desaconseja el uso de este método en iPhone OS 4.0 y versiones posteriores. En su lugar, debe utilizar los métodos de animación basados ​​en bloques.

Ejemplo de animación basada en bloques basada en el comentario de Tom

[UIView transitionWithView:mysuperview 
                  duration:0.75
                   options:UIViewAnimationTransitionFlipFromRight
                animations:^{ 
                    [myview removeFromSuperview]; 
                } 
                completion:nil];
Rafael Vega
fuente
44
Entonces, para ser claros, eso significa usar el primer enfoque (CATransition), no el segundo.
Steve N
2
Sí, es el primer enfoque (CATransition).
NebulaFox
16
@ Steven N, no, significa usar las animaciones basadas en bloques en su UIViewlugar. Son esencialmente lo mismo que beginAnimationsy amigos, pero usan funciones de bloqueo / cierre.
Dan Rosenstark
36
Sí, Yar tiene razón. Así es como se ve una animación de bloque: [UIView transitionWithView:mysuperview duration:0.75 options:UIViewAnimationTransitionFlipFromRight animations:^{ [myview removeFromSuperview]; } completion:nil]Consulte la documentación de UIView para obtener más detalles.
Tom van Zummeren
3
Excepto si desea admitir teléfonos 3.1.3. Entonces no uses bloques.
ZaBlanc
69

He estado usando este último para muchas animaciones ligeras y agradables. Puede usarlo para fundir dos vistas, fundir una frente a otra o fundirla. Puede tomar una vista sobre otra como una pancarta, puede hacer que una vista se estire o encoja ... Estoy obteniendo mucho kilometraje de beginAnimation/ commitAnimations.

No pienses que todo lo que puedes hacer es:

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

Aquí hay una muestra:

[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];

Como puede ver, puede jugar con alfa, cuadros e incluso tamaños de una vista. Jugar. Puede sorprenderse con sus capacidades.

mahboudz
fuente
52

La diferencia parece ser la cantidad de control que necesita sobre la animación.

El CATransitionenfoque le da más control y, por lo tanto, más cosas para configurar, por ejemplo. La función de sincronización. Al ser un objeto, puede almacenarlo para más tarde, refactorizar para apuntar todas sus animaciones para reducir el código duplicado, etc.

Los UIViewmétodos de clase son métodos convenientes para animaciones comunes, pero son más limitados que CATransition. Por ejemplo, solo hay cuatro tipos de transición posibles (voltear a la izquierda, voltear a la derecha, acurrucarse, acurrucarse). Si quisieras hacer un desvanecimiento, deberías cavar hacia abajo para CATransition'sdesvanecer la transición, o configurar una animación explícita del UIViewalfa de tu.

Tenga CATransitionen cuenta que en Mac OS X le permitirá especificar un CoreImagefiltro arbitrario para usar como transición, pero tal como está ahora, no puede hacerlo en el iPhone, que carece CoreImage.

Ryan McCuaig
fuente
77
Tenga en cuenta que este es un consejo de la era iOS 2.0. Vea la respuesta de Rafael Vega sobre métodos basados ​​en bloques si tiene iOS 4.0 o superior.
Ryan McCuaig
También tenga en cuenta que CoreImage ahora está disponible a partir de iOS 5, pero solo algunas de sus características. Creo que puedes usar una transición CoreImage en una animación, pero no puedes hacer filtros CoreImage personalizados en iOS (5).
Aaron Ash
26

Podemos animar imágenes en ios 5 usando este código 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!");
    }];
Gurú
fuente
55
también está disponible en iOS 4 y se conoce como animación "basada en bloques". No está restringido a iOS 5 y posterior.
johnbakers
8

En los UIViewdocumentos, lea sobre esta función para ios4 +

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

De todos modos, el método "Bloquear" se prefiere hoy en día. Explicaré el bloque simple a continuación.

Considere lo recortado a continuación. bug2 y bug 3 son imageViews. La animación a continuación describe una animación con 1 segundo de duración después de un retraso de 1 segundo. El bug3 se mueve desde su centro al centro del bug2. Una vez que se complete la animación, se registrará "¡Animación del centro terminada!".

-(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!");
                 }];
}

Espero que esté limpio !!!

Deepukjayan
fuente
2
usted asignó el CGPoint bug3.center a bug3Center y justo después de eso asignó el CGPoint bug2.center a la misma variable bug3Center? Por qué estás haciendo eso ?
pnizzle
oopss !! eso es un error tipográfico. Actualizado ahora.
Deepukjayan
2

Aquí está el código para la animación suave, podría ser útil para muchos desarrolladores.
Encontré este fragmento de código de este tutorial.

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
fuente
2

intentemos y paguemos por Swift 3 ...

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