Jak stworzyć animację odbijania UIView?


93

Mam następujące przejście CATransition dla wywoływanego UIView finalScoreView, co powoduje, że wchodzi na ekran od góry:

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

Jak sprawić, by odbijał się raz po opadnięciu, a potem pozostał nieruchomo? Powinien nadal wchodzić na ekran od góry, ale potem odbijać się, gdy spadnie.

Każda pomoc byłaby mile widziana, dzięki!


3
Czy celujesz w system iOS7 lub nowszy? Jeśli tak, możesz wykorzystać UIKit Dynamics
WDUK,

Odpowiedzi:


145

Dzięki iOS7 i UIKit Dynamics nie ma już potrzeby używania CAKeyframeAnimationsani UIViewanimacji!

Spójrz na aplikację Apple UIKit Dynamics Catalog . Alternatywnie, Teehanlax ma jasny, zwięzły samouczek z pełnym projektem w github . Jeśli chcesz uzyskać bardziej szczegółowy samouczek o szczegółach dynamiki, samouczek Ray Winderlich jest świetny. Jak zawsze dokumentacja Apple to świetny pierwszy przystanek, więc zapoznaj się z odniesieniem do klasy UIDynamicAnimator w dokumentacji.

Oto fragment kodu z samouczka 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];

A oto wyniki

Kwadratowe odbicie

UIKit Dynamics to naprawdę potężny i łatwy w użyciu dodatek do iOS7, z którego można uzyskać świetnie wyglądający interfejs użytkownika.

Inne przykłady:

Odbicie przycisku

Odbijanie slajdów

Kolekcja sprężysta

Wiosenna kolekcja WWDC

Kroki wdrażania dynamiki UIKit są zawsze takie same:

  1. Utwórz UIDynamicAnimatori przechowuj go w silnej nieruchomości
  2. Utwórz jeden lub więcej UIDynamicBehaviors. Każde zachowanie powinno mieć jeden lub więcej elementów, zazwyczaj widok do animacji.
  3. Upewnij się, że stan początkowy elementów użytych w symulacji UIDynamicBehaviorsjest prawidłowym stanem UIDynamicAnimator.

1
Cześć Michael, wielkie dzięki za pomoc! To zdecydowanie wygląda na niezwykle łatwe do zrobienia! Wypróbowałem to i działa, gdy uderza w dół widoku, ale nie działa z innym widokiem - stackoverflow.com/questions/21895674/… - Bardzo chciałbym, abyś mógł mi tam pomóc! :) Dzięki
user3127576,

2
WSPANIAŁY samouczek, ALE po prostu użyjesz jednej linii kodu, używając SpringWithDamping, do odbicia!
Fattie

2
Czy możesz udostępnić przykładowy kod do animacji odbijania Uitableview, jak powyżej. Próbuję z UITableview, ale nie jestem pewien, od czego zacząć.
Dinesh

1
UIKit Dynamics świetnie sprawdza się w przypadku przykładowych spraw. Ale jeśli chodzi o rzeczywiste zadania, widzisz, jakie to surowe i ograniczone. Jednym dużym problemem jest nadpisywanie UIDynamicItemBehavior(co w rzeczywistości jest właściwościami, a nie zachowaniem). Nie możesz po prostu używać różnych właściwości fizycznych w różnych zachowaniach. Innym przypadkiem jest implementacja gumowych obwiedni podobnych do UIScrollView - jest to bardzo skomplikowane. Mogę napisać jeszcze więcej, ale komentarz jest za krótki.
kelin

2
proszę dodać pełny kod. Twój kod opisuje, jak tworzyć UIDynamicAnimatori obiekty z nim powiązane, ale nie odpowiada, jak ich używać
Vyachaslav Gerchicov

263

Prostszą alternatywą dla UIDynamicAnimatoriOS 7 jest Spring Animation (nowa i potężna animacja bloku UIView), która może dać ładny efekt odbijania z tłumieniem i prędkością: Cel C

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

Szybki

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 == bardzo sprężysty. 1.0 sprawia, że ​​płynnie zwalnia bez przeregulowania.

initialSpringVelocityto z grubsza „pożądana odległość podzielona przez pożądane sekundy”. 1.0 odpowiada całkowitej odległości animacji pokonanej w ciągu jednej sekundy. Na przykład, całkowita odległość animacji wynosi 200 punktów i chcesz, aby początek animacji odpowiadał prędkości oglądania 100 pkt / s, użyj wartości 0,5.

Bardziej szczegółowy samouczek i przykładową aplikację można znaleźć w tym samouczku . Mam nadzieję, że komuś się to przyda.


2
Oto projekt demonstracyjny, który stworzyłem, aby pomóc Ci uzyskać odpowiednią animację. Cieszyć się! github.com/jstnheo/SpringDampingDemo
jstn

Pozdrowienia dla tego projektu demonstracyjnego, kolego. Naprawdę pomaga zrozumieć te wartości, ponieważ są dość tępe. Chciałbym, żeby Apple uczynił je jaśniejszymi
kakubei

32

Oto projekt demonstracyjny, który stworzyłem, aby pomóc Ci uzyskać odpowiednią animację. Cieszyć się!

SpringDampingDemo

wprowadź opis obrazu tutaj


Pozdrowienia dla tego projektu demonstracyjnego, kolego. Naprawdę pomaga zrozumieć te wartości, ponieważ są dość tępe. Chciałbym, żeby Apple uczynił je jaśniejszymi
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
W kodzie nie ma wyjaśnienia ani komentarza. To nie jest pomocne
Lorenzo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.