【问题标题】:Mimic UIAlertView Bounce?模仿 UIAlertView 反弹?
【发布时间】:2011-01-10 17:39:33
【问题描述】:

从 iPhone 上的 UIAlertView 模拟弹跳动画的最佳方法是什么?是否有一些内置机制? UIAlertView 本身无法满足我的需求。

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

【问题讨论】:

    标签: ios iphone cocoa-touch uikit core-animation


    【解决方案1】:

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

    【讨论】:

    • 谢谢,谢谢,谢谢。我已经为此苦苦挣扎了一段时间。
    【解决方案2】:

    我研究了如何通过调动-[CALayer addAnimation:forKey:] 将动画添加到UIAlertView 的图层。以下是我为它执行的缩放变换动画得到的值:

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

    有持续时间

    0.2s, 0.1s, 0.1s.

    所有动画都使用缓入/缓出计时功能。这是封装了这个逻辑的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 使用的。
    【解决方案3】:

    您可以使用 2 个动画,一个弹出到非常大,另一个重新缩放到正常大小。

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

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

    【讨论】:

    • 谢谢!这很有帮助。
    【解决方案4】:

    这是我为我正在开发的应用程序所做的。当你按下视图时,我想要的效果是弹跳。尝试使用适合您的口味和所需效果速度的值。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-20
      • 1970-01-01
      • 2011-05-13
      • 1970-01-01
      • 2013-07-19
      • 1970-01-01
      • 2014-02-09
      相关资源
      最近更新 更多