2010-01-29 5 views
15

Quel est le meilleur moyen d'imiter l'animation de rebond de l'UIAlertView sur l'iPhone? Y a-t-il un mécanisme intégré pour cela? Le UIAlertView lui-même ne fonctionnera pas pour mes besoins. J'ai regardé dans les courbes d'animation, mais d'après ce que je peux dire, les seules qu'elles fournissent sont easyIn, easeOut, et linear.Mimic UIAlertView Bounce?

Répondre

3

Vous pouvez utiliser 2 animations, l'une pour faire apparaître une image très grande et l'autre pour revenir à la taille normale.

(Ceci est l'utilisation de l'approche par UIAlertView interne.)

Vous pouvez également utiliser le niveau inférieur CAAnimation et utiliser +[CAMediaTimingFunction functionWithControlPoints::::] pour faire votre propre courbe.

+0

Merci! C'était très utile. –

62

UIAlertView utilise une animation plus sophistiquée:

  • échelle supérieure à 100%
  • échelle inférieure à 100%
  • échelle à 100%

Voici une mise en œuvre au moyen d'un 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

Merci, merci, merci. J'ai lutté avec ça pendant un moment. –

+0

merci cela a fonctionné .... – Leena

+0

+1 Merci beaucoup. Ça marche pour moi ... :) – python

30

J'ai étudié comment les animations sont ajoutées à la couche de UIAlertView en balayant -[CALayer addAnimation:forKey:]. Voici les valeurs que j'ai pour l'échelle de transformer les animations qu'il effectue:

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

avec des durées

0.2s, 0.1s, 0.1s. Toutes les animations utilisent une fonction de temporisation de facilité/décélération. Voici un CAKeyframeAnimation qui encapsule cette logique:

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

Je crois UIAlertView réalise également une animation simple d'opacité 0.0f-1.0f sur la durée totale de la transformée animation (0.4).

+2

Vous êtes l'homme de la folie. – featherless

+0

C'est à votre préférence personnelle. Mais les temps clés que j'ai fournis sont exactement ce que UIAlertView utilise. – LucasTizma

+0

C'est génial, merci. –

0

Voici comment je l'ai fait pour une application sur laquelle je travaille. L'effet que j'allais faire était de rebondir quand vous avez appuyé sur la vue. Expérimentez avec les valeurs selon votre goût et la vitesse désirée de l'effet.

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