¿Cómo crear una animación de rebote de UIView?

92

Tengo el siguiente CATransition para un UIView llamado finalScoreView, lo que hace que ingrese a la pantalla desde la parte superior:

CATransition *animation = [CATransition animation];
animation.duration = 0.2;
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromBottom;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

[gameOver.layer addAnimation:animation forKey:@"changeTextTransition"];
[finalScoreView.layer addAnimation:animation forKey:@"changeTextTransition"];

¿Cómo hago para que rebote una vez después de bajar y luego se quede quieto? Debería ingresar a la pantalla desde la parte superior, pero luego rebotar cuando baje.

Cualquier ayuda será muy apreciada, ¡gracias!

usuario3127576
fuente
3
¿Está apuntando a iOS7 y superior? Si es así, podría aprovechar UIKit Dynamics
WDUK

Respuestas:

144

Con iOS7 y UIKit Dynamics, ya no es necesario utilizar CAKeyframeAnimations o UIViewanimaciones!

Eche un vistazo a la aplicación UIKit Dynamics Catalog de Apple . Alternativamente, Teehanlax tiene un tutorial claro y conciso con el proyecto completo en github . Si desea un tutorial más detallado sobre los entresijos de la dinámica, el tutorial de Ray Winderlich es genial. Como siempre, los documentos de Apple son una excelente primera parada, así que consulte la referencia de la clase UIDynamicAnimator en los documentos.

Aquí hay un poco del código del tutorial de Teenhanlax:

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

UIGravityBehavior* gravityBehavior = 
                [[UIGravityBehavior alloc] initWithItems:@[self.redSquare]];
[self.animator addBehavior:gravityBehavior];

UICollisionBehavior* collisionBehavior = 
                [[UICollisionBehavior alloc] initWithItems:@[self.redSquare]]; 
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collisionBehavior];

UIDynamicItemBehavior *elasticityBehavior = 
                [[UIDynamicItemBehavior alloc] initWithItems:@[self.redSquare]];
elasticityBehavior.elasticity = 0.7f;
[self.animator addBehavior:elasticityBehavior];

Y aquí están los resultados

Rebote cuadrado

UIKit Dynamics es una adición realmente poderosa y fácil de usar a iOS7 y puede obtener una interfaz de usuario de excelente apariencia.

Otros ejemplos:

Rebote del botón Deslizar rebote Colección Springy Colección sprint de la WWDC

Los pasos para implementar la dinámica UIKit son siempre los mismos:

  1. Cree un UIDynamicAnimatory guárdelo en una propiedad sólida
  2. Crea uno o más UIDynamicBehaviors. Cada comportamiento debe tener uno o más elementos, normalmente una vista para animar.
  3. Asegúrese de que el estado inicial de los elementos utilizados en el UIDynamicBehaviorses un estado válido dentro de la UIDynamicAnimatorsimulación.
memmons
fuente
1
Hola Michael, ¡muchas gracias por tu ayuda! ¡Esto definitivamente parece extremadamente fácil de hacer! Lo probé y funciona cuando llega a la parte inferior de la vista, pero no funciona con otra vista - stackoverflow.com/questions/21895674/… - ¡Me encantaría si pudieras ayudarme! :) Gracias
user3127576
2
UN MAGNÍFICO tutorial, ¡PERO solo usarías una línea de código, usando SpringWithDamping, para un rebote!
Fattie
2
¿Puede compartir algún ejemplo de código para la animación de rebote de Uitableview como se muestra arriba? Estoy intentando con UITableview pero no estoy seguro de por dónde empezar.
Dinesh
1
UIKit Dynamics es excelente cuando se trata de casos de ejemplo. Pero cuando se trata de tareas reales, se ve cuán crudo y restringido es. Un gran problema es anular UIDynamicItemBehavior(que en realidad son propiedades, no comportamiento). No puede simplemente usar diferentes propiedades físicas en diferentes comportamientos. Otro caso es la implementación de límites de goma similares a UIScrollView; es muy complicado. Puedo escribir aún más, pero el comentario es demasiado corto.
Kelin
2
agregue el código completo por favor. Su código describe cómo crear UIDynamicAnimatory los objetos asociados con él, pero no responde cómo usarlos
Vyachaslav Gerchicov
261

Una alternativa más simple que UIDynamicAnimatoren iOS 7 es Spring Animation (una nueva y poderosa animación de bloques UIView), que puede brindarle un agradable efecto de rebote con amortiguación y velocidad: Objective C

[UIView animateWithDuration:duration
  delay:delay
  usingSpringWithDamping:damping
  initialSpringVelocity:velocity
  options:options animations:^{
    //Animations
    }
  completion:^(BOOL finished) {
    //Completion Block
}];

Rápido

UIView.animateWithDuration(duration,
     delay: delay,
     usingSpringWithDamping: damping,
     initialSpringVelocity: velocity,
     options: options,
     animations: {
            //Do all animations here
            }, completion: {
            //Code to run after animating
                (value: Bool) in
        })

Swift 4.0

UIView.animate(withDuration:duration,
     delay: delay,
     usingSpringWithDamping: damping,
     initialSpringVelocity: velocity,
     options: options,
     animations: {
            //Do all animations here
            }, completion: {
            //Code to run after animating
                (value: Bool) in
        })

usingSpringWithDamping 0.0 == muy hinchable. 1.0 hace que desacelere suavemente sin sobrepasar.

initialSpringVelocityes, aproximadamente, "distancia deseada, dividida por segundos deseados". 1.0 corresponde a la distancia total de animación recorrida en un segundo. Por ejemplo, la distancia total de la animación es de 200 puntos y desea que el inicio de la animación coincida con una velocidad de visualización de 100 pt / s, utilice un valor de 0,5.

Tutorial más detallado y aplicación de ejemplo se pueden encontrar en este tutorial . Espero que esto sea útil para alguien.

huong
fuente
2
Aquí hay un proyecto de demostración que creé para ayudarlo a obtener la animación perfecta. ¡Disfrutar! github.com/jstnheo/SpringDampingDemo
jstn
Saludos por ese proyecto de demostración, amigo. Realmente ayuda a descifrar estos valores ya que son bastante obtusos. Ojalá Apple los hubiera
aclarado
32

Aquí hay un proyecto de demostración que creé para ayudarlo a obtener la animación perfecta. ¡Disfrutar!

SpringDampingDemo

ingrese la descripción de la imagen aquí

jstn
fuente
Saludos por ese proyecto de demostración, amigo. Realmente ayuda a descifrar estos valores ya que son bastante obtusos. Ojalá Apple los hubiera
aclarado
-1
- (IBAction)searchViewAction:(UIButton*)sender
{
  if(sender.tag == 0)
  {
    sender.tag = 1;

    CGRect optionsFrame2 = self.defaultTopView.frame;
    optionsFrame2.origin.x = -320;

    CGRect optionsFrame = self.searhTopView.frame;
    optionsFrame.origin.x = 320;
    self.searhTopView.frame = optionsFrame;

    [UIView animateWithDuration:1.0 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 options:0 animations:^{

        CGRect optionsFrame = self.searhTopView.frame;

        optionsFrame.origin.x = 0;
        self.searhTopView.frame = optionsFrame;
        self.defaultTopView.frame = optionsFrame2;
    } completion:^(BOOL finished) {
    }];        
}
else
{
    sender.tag = 0;

    CGRect optionsFrame2 = self.defaultTopView.frame;
    optionsFrame2.origin.x = 0;

    CGRect optionsFrame = self.searhTopView.frame;
    optionsFrame.origin.x = 320;

    [UIView animateWithDuration:1.0 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 options:0 animations:^{

        CGRect optionsFrame = self.searhTopView.frame;

        optionsFrame.origin.x = 320;
        self.searhTopView.frame = optionsFrame;
        self.defaultTopView.frame = optionsFrame2;
    } completion:^(BOOL finished) {
    }];
}
}
Espía
fuente
1
No hay explicación en el código ni comentarios. Esto no es útil
Lorenzo