2010-01-29 16 views
15

Was ist der beste Weg, um die Bouncing-Animation von der UIAlertView auf dem iPhone nachzuahmen? Gibt es dafür einen eingebauten Mechanismus? Das UIAlertView selbst wird nicht für meine Bedürfnisse funktionieren.Mimic UIAlertView Bounce?

Ich habe mich in Animationskurven umgeschaut, aber von dem, was ich sagen kann, sind die einzigen, die sie bieten, easeIn, easeOut und linear.

Antwort

3

Sie können 2 Animationen verwenden, von denen die eine zu sehr groß und die andere auf die normale Größe skaliert wird.

(Dies ist der Ansatz, den Einsatz von UIAlertView intern.)

Alternativ können Sie die untere Ebene CAAnimation verwenden und +[CAMediaTimingFunction functionWithControlPoints::::] verwenden, um Ihre eigene Kurve zu machen.

+0

Vielen Dank! Das war sehr hilfreich. –

62

UIAlertView verwendet eine komplexere Animation:

  • Maßstab größer als 100%
  • Skala kleiner als 100%
  • Skala bis 100%

Hier ist eine Implementierung einer mit 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

Danke, danke, danke. Ich habe eine Weile damit zu kämpfen. –

+0

danke es hat funktioniert .... – Leena

+0

+1 Vielen Dank. Es funktioniert für mich ... :) – python

30

Ich habe untersucht, wie Animationen zu UIAlertView 's Schicht hinzugefügt werden, indem Sie -[CALayer addAnimation:forKey:] swizzlen. Hier sind die Werte, die ich für die Skala bekam verwandeln Animationen es führt:

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

mit Dauern

0.2s, 0.1s, 0.1s.

Alle Animationen verwenden eine einfache Ein-/Ausstiegsfunktion. Hier ist eine CAKeyframeAnimation, die diese Logik kapselt:

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

Ich glaube UIAlertView auch eine einfache Opazität Animation 0.0f-1.0f über die gesamte Dauer der Animation verwandeln führt (0.4).

+2

Du bist der verdammte Mann. – featherless

+0

Es liegt an den persönlichen Vorlieben. Aber die Schlüsselzeiten, die ich zur Verfügung stelle, sind genau das, was 'UIAlertView' benutzt. – LucasTizma

+0

Das ist großartig, danke. –

0

So habe ich es für eine App gemacht, an der ich arbeite. Der Effekt, den ich anstrebte, war, wenn Sie die Ansicht drückten. Experimentieren Sie mit den Werten nach Ihrem Geschmack und der gewünschten Geschwindigkeit des Effekts.

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