Как создать анимацию отказов UIView?

93

У меня есть следующий CATransition для вызываемого UIView finalScoreView, который заставляет его входить на экран сверху:

CATransition *animation = [CATransition animation];
animation.duration = 0.2;
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromBottom;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

[gameOver.layer addAnimation:animation forKey:@"changeTextTransition"];
[finalScoreView.layer addAnimation:animation forKey:@"changeTextTransition"];

Как мне сделать так, чтобы он отскакивал один раз после падения, а затем оставался на месте? Он все равно должен входить на экран сверху, но затем подпрыгивать, когда опускается.

Любая помощь будет принята с благодарностью, спасибо!

user3127576
источник
3
Вы ориентируетесь на iOS7 и выше? Если да, то вы могли бы использовать UIKit Dynamics
WDUK

Ответы:

145

С iOS7 и UIKit Dynamics больше нет необходимости использовать CAKeyframeAnimationsили UIViewанимацию!

Взгляните на приложение Apple UIKit Dynamics Catalog . В качестве альтернативы у Teehanlax есть четкое и краткое руководство с полным проектом на github . Если вам нужен более подробный учебник по тонкостям динамики, отлично подойдет руководство Рэя Виндерлиха . Как всегда, документы Apple - отличная первая остановка, поэтому ознакомьтесь со ссылкой на класс UIDynamicAnimator в документации.

Вот фрагмент кода из учебника Teenhanlax:

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

UIGravityBehavior *gravityBehavior = 
                [[UIGravityBehavior alloc] initWithItems:@[self.redSquare]];
[self.animator addBehavior:gravityBehavior];
    
UICollisionBehavior *collisionBehavior = 
                [[UICollisionBehavior alloc] initWithItems:@[self.redSquare]]; 
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collisionBehavior];
    
UIDynamicItemBehavior *elasticityBehavior = 
                [[UIDynamicItemBehavior alloc] initWithItems:@[self.redSquare]];
elasticityBehavior.elasticity = 0.7f;
[self.animator addBehavior:elasticityBehavior];

И вот результаты

Квадратный отскок

UIKit Dynamics - действительно мощное и простое в использовании дополнение к iOS7, и вы можете получить от него отличный пользовательский интерфейс.

Другие примеры:

Отскок кнопки

Отскок слайда

Пружинная коллекция

Весенняя коллекция WWDC

Шаги по реализации динамики UIKit всегда одинаковы:

  1. Создайте UIDynamicAnimatorи храните его в надежном месте
  2. Создайте один или несколько UIDynamicBehaviors. Каждое поведение должно иметь один или несколько элементов, обычно это представление для анимации.
  3. Убедитесь, что исходное состояние элементов, используемых в, UIDynamicBehaviorsявляется допустимым состоянием в рамках UIDynamicAnimatorмоделирования.
меммоны
источник
1
Привет, Майкл, большое спасибо за помощь! Это определенно выглядит очень легко! Я попробовал, и он работает, когда он попадает в нижнюю часть представления, но он не работает с другим представлением - stackoverflow.com/questions/21895674/… - Я был бы рад, если бы вы могли мне помочь! :) Спасибо
user3127576
2
ВЕЛИКОЛЕПНОЕ руководство, НО вы бы просто использовали одну строчку кода, используя SpringWithDamping, для отскока!
Fattie 08
2
Не могли бы вы поделиться образцом кода для анимации отскока Uitableview, как указано выше. Я пытаюсь использовать UITableview, но не знаю, с чего начать.
Динеш
1
UIKit Dynamics отлично подходит, когда вы имеете дело с примерами. Но когда дело доходит до реальных задач, вы видите, насколько это сырое и ограниченное. Одна большая проблема - это переопределение UIDynamicItemBehavior(что на самом деле является свойствами, а не поведением). Вы не можете просто использовать разные физические свойства для разного поведения. Другой случай - реализация резиновых границ типа UIScrollView - это очень сложно. Я могу написать еще больше, но комментарий слишком короткий.
келин
2
добавьте, пожалуйста, полный код. Ваш код описывает, как создавать, UIDynamicAnimatorи связанные с ним объекты, но не отвечает, как их использовать
Вячеслав Герчиков
263

Более простой альтернативой UIDynamicAnimatoriOS 7 является Spring Animation (новая и мощная блочная анимация UIView), которая может дать вам хороший эффект подпрыгивания с демпфированием и скоростью: Цель C

[UIView animateWithDuration:duration
  delay:delay
  usingSpringWithDamping:damping
  initialSpringVelocity:velocity
  options:options animations:^{
    //Animations
    }
  completion:^(BOOL finished) {
    //Completion Block
}];

Swift

UIView.animateWithDuration(duration,
     delay: delay,
     usingSpringWithDamping: damping,
     initialSpringVelocity: velocity,
     options: options,
     animations: {
            //Do all animations here
            }, completion: {
            //Code to run after animating
                (value: Bool) in
        })

Swift 4.0

UIView.animate(withDuration:duration,
     delay: delay,
     usingSpringWithDamping: damping,
     initialSpringVelocity: velocity,
     options: options,
     animations: {
            //Do all animations here
            }, completion: {
            //Code to run after animating
                (value: Bool) in
        })

usingSpringWithDamping 0.0 == очень бодрый. 1.0 обеспечивает плавное замедление без превышения скорости.

initialSpringVelocityгрубо говоря, «желаемое расстояние, разделенное на желаемые секунды». 1.0 соответствует общему расстоянию анимации, пройденному за одну секунду. Например, общее расстояние анимации составляет 200 точек, и вы хотите, чтобы начало анимации соответствовало скорости просмотра 100 pt / s, используйте значение 0,5.

Более подробное руководство и образец приложения можно найти в этом руководстве . Надеюсь, это кому-то пригодится.

Хуонг
источник
2
Вот демонстрационный проект, который я создал, чтобы помочь вам получить правильную анимацию. Наслаждайтесь! github.com/jstnheo/SpringDampingDemo
jstn
Приветствую этот демонстрационный проект, приятель. Действительно помогает понять эти значения, поскольку они довольно тупые. Я бы хотел, чтобы Apple сделала их более понятными
kakubei
32

Вот демонстрационный проект, который я создал, чтобы помочь вам получить правильную анимацию. Наслаждайтесь!

SpringDampingДемо

введите описание изображения здесь

jstn
источник
Приветствую этот демонстрационный проект, приятель. Действительно помогает понять эти значения, поскольку они довольно тупые. Я бы хотел, чтобы Apple сделала их более понятными
kakubei
-1
- (IBAction)searchViewAction:(UIButton*)sender
{
  if(sender.tag == 0)
  {
    sender.tag = 1;

    CGRect optionsFrame2 = self.defaultTopView.frame;
    optionsFrame2.origin.x = -320;

    CGRect optionsFrame = self.searhTopView.frame;
    optionsFrame.origin.x = 320;
    self.searhTopView.frame = optionsFrame;

    [UIView animateWithDuration:1.0 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 options:0 animations:^{

        CGRect optionsFrame = self.searhTopView.frame;

        optionsFrame.origin.x = 0;
        self.searhTopView.frame = optionsFrame;
        self.defaultTopView.frame = optionsFrame2;
    } completion:^(BOOL finished) {
    }];        
}
else
{
    sender.tag = 0;

    CGRect optionsFrame2 = self.defaultTopView.frame;
    optionsFrame2.origin.x = 0;

    CGRect optionsFrame = self.searhTopView.frame;
    optionsFrame.origin.x = 320;

    [UIView animateWithDuration:1.0 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 options:0 animations:^{

        CGRect optionsFrame = self.searhTopView.frame;

        optionsFrame.origin.x = 320;
        self.searhTopView.frame = optionsFrame;
        self.defaultTopView.frame = optionsFrame2;
    } completion:^(BOOL finished) {
    }];
}
}
Шпион
источник
1
В коде нет пояснений и комментариев. Это бесполезно
Лоренцо