2010-01-29 16 views
15

¿Cuál es la mejor manera de imitar la animación de rebote del UIAlertView en el iPhone? ¿Hay algún mecanismo incorporado para esto? El UIAlertView en sí no funcionará para mis necesidades.Mimic UIAlertView Bounce?

Miré en las curvas de animación, pero por lo que puedo decir, las únicas que proporcionan son easeIn, easeout y lineales.

Respuesta

3

Puede usar 2 animaciones, una para que aparezca hasta muy grande, y la otra para volver a escalar a su tamaño normal.

(Esto es el uso de enfoque por UIAlertView internamente.)

Alternativamente, se puede utilizar el nivel más bajo CAAnimation+[CAMediaTimingFunction functionWithControlPoints::::] y utilizar para hacer su propia curva.

+0

¡Gracias! Esto fue muy útil. –

62

UIAlertView utiliza una animación más sofisticado:

  • escala a más de 100%
  • escala menor que 100%
  • escala a 100%

He aquí una aplicación utilizando una CAKeyFrameAnimation:

view.alpha = 0; 
[UIView animateWithDuration:0.1 animations:^{view.alpha = 1.0;}]; 

CAKeyframeAnimation *bounceAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"]; 
bounceAnimation.values = @[@0.01f, @1.1f, @0.8f, @1.0f]; 
bounceAnimation.keyTimes = @[@0.0f, @0.5f, @0.75f, @1.0f]; 
bounceAnimation.duration = 0.4; 
[view.layer addAnimation:bounceAnimation forKey:@"bounce"]; 
+0

Gracias, gracias, gracias. He estado luchando con esto por un tiempo. –

+0

gracias funcionó .... – Leena

+0

+1 Muchas gracias. Funciona para mí ... :) – python

30

Investigé cómo se agregan las animaciones a la capa UIAlertView al voltear -[CALayer addAnimation:forKey:]. Estos son los valores que tengo para transformar la escala que realiza animaciones:

0.01f -> 1.10f -> 0.90f -> 1.00f

con duraciones

0.2s, 0.1s, 0.1s.

Todas las animaciones utilizan una función de temporización de facilidad/facilidad. Aquí está una CAKeyframeAnimation que encapsula esta lógica:

CAKeyframeAnimation *bounceAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; 
bounceAnimation.fillMode = kCAFillModeBoth; 
bounceAnimation.removedOnCompletion = YES; 
bounceAnimation.duration = 0.4; 
bounceAnimation.values = @[ 
    [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.01f, 0.01f, 0.01f)], 
    [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1f, 1.1f, 1.1f)], 
    [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9f, 0.9f, 0.9f)], 
    [NSValue valueWithCATransform3D:CATransform3DIdentity]]; 
bounceAnimation.keyTimes = @[@0.0f, @0.5f, @0.75f, @1.0f]; 
bounceAnimation.timingFunctions = @[ 
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], 
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], 
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; 

Creo UIAlertView también realiza una animación simple opacidad 0.0f-1.0f largo de la duración total de la animación de transformación (0.4).

+2

Eres el hombre maldito. – featherless

+0

Depende de las preferencias personales. Pero las horas clave que proporcioné son exactamente lo que 'UIAlertView' está usando. – LucasTizma

+0

Esto es increíble, gracias. –

0

Así es como lo hice para una aplicación en la que estoy trabajando. El efecto que estaba buscando rebotaba cuando presionaste la vista. Experimenta con los valores para satisfacer tu gusto y la velocidad deseada del efecto.

- (void) bounceView:(UIView*)bouncer 
{ 
    // set duration to whatever you want 
    float duration = 1.25; 
    // use a consistent frame rate for smooth animation. 
    // experiment to your taste 
    float numSteps = 15 * duration; 

    // scale the image up and down, halving the distance each time 
    [UIView animateKeyframesWithDuration:duration 
            delay:0 
           options:UIViewKeyframeAnimationOptionCalculationModeCubic 
           animations:^{ 
            float minScale = 0.50f; // minimum amount of shrink 
            float maxScale = 1.75f; // maximum amount of grow 
            for(int i = 0; i< numSteps*2; i+=2) 
            { 
             // bounce down 
             [UIView addKeyframeWithRelativeStartTime:duration/numSteps * i 
                   relativeDuration:duration/numSteps 
                    animations:^{ 
                     bouncer.layer.transform = CATransform3DMakeScale(minScale, minScale, 1); 
                    }]; 
             // bounce up 
             [UIView addKeyframeWithRelativeStartTime:duration/numSteps * (i+1) 
                   relativeDuration:duration/numSteps 
                    animations:^{ 
                     bouncer.layer.transform = CATransform3DMakeScale(maxScale, maxScale, 1); 
                    }]; 

             // cut min scale halfway to identity 
             minScale = minScale + (1.0f - minScale)/2.0f; 
             // cut max scale halfway to identity 
             maxScale = 1.0f + (maxScale - 1.0f)/2.0f; 
            } 
           } completion:^(BOOL finished) { 
            // quickly smooth out any rounding errors 
            [UIView animateWithDuration:0.5*duration/numSteps animations:^{ 
             bouncer.layer.transform = CATransform3DIdentity; 
            }]; 
           }]; 
}