Mimic UIAlertView Bounce? - PullRequest
       14

Mimic UIAlertView Bounce?

15 голосов
/ 29 января 2010

Каков лучший способ имитировать прыгающую анимацию из UIAlertView на iPhone? Есть ли какой-то встроенный механизм для этого? Сам UIAlertView не будет работать для моих нужд.

Я посмотрел на кривые анимации, но из того, что я могу сказать, единственные, которые они предоставляют, - easyIn, easeOut и linear.

Ответы [ 4 ]

62 голосов
/ 17 ноября 2010

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"];
30 голосов
/ 17 октября 2012

Я исследовал, как анимации добавляются к слою UIAlertView с помощью быстрого -[CALayer addAnimation:forKey:]. Вот значения, которые я получил для анимации преобразования масштаба, которую он выполняет:

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.0f до 1.0f в течение общей продолжительности анимации преобразования (0.4).

3 голосов
/ 29 января 2010

Вы можете использовать 2 анимации, одну для всплывающего окна очень большого размера, а другую - для изменения масштаба до нормального размера.

(Это подход, используемый UIAlertView внутри.)

В качестве альтернативы, вы можете использовать нижний уровень CAAnimation и использовать +[CAMediaTimingFunction functionWithControlPoints::::], чтобы создать собственную кривую.

0 голосов
/ 09 марта 2014

Вот как я это сделал для приложения, над которым я работаю. Эффект, к которому я стремился, был подпрыгивающим, когда вы нажимали на вид. Поэкспериментируйте со значениями по своему вкусу и желаемой скоростью эффекта.

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