模仿UIAlertView的弹跳效果?

15

如何最好地模仿iPhone上UIAlertView的弹跳动画?是否有一些内置机制可以实现此功能?对我来说,UIAlertView本身无法满足我的需求。

我研究了动画曲线,但据我所知,它们提供的唯一曲线是easeIn、easeOut和linear。

4个回答

62

UIAlertView使用了一种更复杂的动画:

  • 放大超过100%
  • 缩小小于100%
  • 缩放到100%

这里是一个使用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"];

谢谢,谢谢,谢谢。我已经苦苦挣扎了一段时间。 - Stig Brautaset

30

通过交换 -[CALayer addAnimation:forKey:] 方法,我调查了如何将动画添加到 UIAlertView 的图层中。以下是缩放变换动画的值:

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

对应的持续时间为

0.2秒,0.1秒,0.1秒.

所有动画都使用了 ease-in/ease-out 的时间函数。这是一个封装了该逻辑的 CAKeyframeAnimation

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

我相信 UIAlertView 也会在转换动画的总持续时间 (0.4) 中执行一个从 0.0f1.0f 的简单不透明度动画。


这取决于个人喜好。但是我提供的关键时间正是 UIAlertView 使用的时间。 - CIFilter

3

您可以使用两种动画,一种用于弹出到非常大的尺寸,另一种用于缩小回正常大小。

(这是UIAlertView内部使用的方法。)

或者,您可以使用较低级别的CAAnimation并使用+[CAMediaTimingFunction functionWithControlPoints::::]创建自己的曲线。


0
这是我在一个正在开发的应用程序中实现它的方法。我想要的效果是在按下视图时弹跳。根据您的口味和所需效果的速度进行值的实验。
- (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;
                                  }];
                              }];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接