Najlepsze praktyki w zakresie animacji iPhone UIView

142

Co jest uważane za najlepszą praktykę dotyczącą animowania przejść widoków na iPhonie?

Na przykład ViewTransitionsprzykładowy projekt firmy Apple używa kodu takiego jak:

CATransition *applicationLoadViewIn = [CATransition animation];
[applicationLoadViewIn setDuration:1];
[applicationLoadViewIn setType:kCATransitionReveal];
[applicationLoadViewIn setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
[[myview layer] addAnimation:applicationLoadViewIn forKey:kCATransitionReveal];

ale w sieci krążą też fragmenty kodu, które wyglądają tak:

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:myview cache:YES];
[myview removeFromSuperview];
[UIView commitAnimations];

Jakie jest najlepsze podejście? Byłoby bardzo mile widziane, gdybyś mógł również podać fragment kodu.

UWAGA: nie udało mi się uzyskać drugiego podejścia do prawidłowego działania.

Keith Fitzgerald
źródło

Odpowiedzi:

118

Z sekcji referencyjnej UIView dotyczącej beginAnimations:context:metody:

Używanie tej metody jest odradzane w systemie iPhone OS 4.0 i nowszych. Zamiast tego należy używać metod animacji opartych na blokach.

Np. Animacji opartej na blokach na podstawie komentarza Toma

[UIView transitionWithView:mysuperview 
                  duration:0.75
                   options:UIViewAnimationTransitionFlipFromRight
                animations:^{ 
                    [myview removeFromSuperview]; 
                } 
                completion:nil];
Rafael Vega
źródło
4
Więc… żeby było jasne, oznacza to użycie pierwszego podejścia (przejście CAT), a nie drugiego?
Steve N
2
Tak, jest to pierwsze podejście (CATransition).
NebulaFox
16
@Steven N, nie, oznacza to, że UIViewzamiast tego użyć animacji blokowych . Są zasadniczo takie same jak beginAnimationsi przyjaciele, ale używają funkcji blokowania / zamykania.
Dan Rosenstark
36
Tak, Yar ma rację. Oto jak wygląda animacja bloku: [UIView transitionWithView:mysuperview duration:0.75 options:UIViewAnimationTransitionFlipFromRight animations:^{ [myview removeFromSuperview]; } completion:nil]Sprawdź dokumentację UIView, aby uzyskać szczegółowe informacje.
Tom van Zummeren,
3
Chyba że chcesz obsługiwać telefony 3.1.3. Więc nie używaj bloków.
ZaBlanc
69

Używałem tego ostatniego do wielu fajnych, lekkich animacji. Możesz go użyć do przenikania dwóch widoków, zanikania jednego przed drugim lub wygaszania. Możesz sfotografować widok na inny jak baner, możesz rozciągnąć lub zmniejszyć widok ... Dostaję dużo kilometrów z beginAnimation/ commitAnimations.

Nie myśl, że wszystko, co możesz zrobić, to:

[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:myview cache:YES];

Oto próbka:

[UIView beginAnimations:nil context:NULL]; {
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationDelegate:self];
    if (movingViewIn) {
// after the animation is over, call afterAnimationProceedWithGame
//  to start the game
        [UIView setAnimationDidStopSelector:@selector(afterAnimationProceedWithGame)];

//      [UIView setAnimationRepeatCount:5.0]; // don't forget you can repeat an animation
//      [UIView setAnimationDelay:0.50];
//      [UIView setAnimationRepeatAutoreverses:YES];

        gameView.alpha = 1.0;
        topGameView.alpha = 1.0;
        viewrect1.origin.y = selfrect.size.height - (viewrect1.size.height);
        viewrect2.origin.y = -20;

        topGameView.alpha = 1.0;
    }
    else {
    // call putBackStatusBar after animation to restore the state after this animation
        [UIView setAnimationDidStopSelector:@selector(putBackStatusBar)];
        gameView.alpha = 0.0;
        topGameView.alpha = 0.0;
    }
    [gameView setFrame:viewrect1];
    [topGameView setFrame:viewrect2];

} [UIView commitAnimations];

Jak widać, możesz bawić się alfa, ramkami, a nawet rozmiarami widoku. Grać. Możesz być zaskoczony jego możliwościami.

mahboudz
źródło
52

Wydaje się, że różnica polega na stopniu kontroli nad animacją.

Takie CATransitionpodejście zapewnia większą kontrolę, a tym samym więcej rzeczy do skonfigurowania, np. funkcja pomiaru czasu. Będąc obiektem, możesz go przechowywać na później, refaktoryzować, aby kierować na niego wszystkie animacje, aby zredukować zduplikowany kod itp.

Te UIViewmetody są metodami klasy wygoda dla typowych animacji, ale są bardziej ograniczone niż CATransition. Na przykład istnieją tylko cztery możliwe typy przejść (odwróć w lewo, odwróć w prawo, zawiń w górę, zawiń w dół). Jeśli chciałbyś wprowadzić fade in, musiałbyś albo zagłębić się w dół, żeby CATransition'sprzejść do fade, albo ustawić wyraźną animację swojej UIViewalfa.

Zauważ, że CATransitionw systemie Mac OS X pozwoli ci określić dowolny CoreImagefiltr do użycia jako przejście, ale w obecnej postaci nie możesz tego zrobić na iPhonie, którego brakuje CoreImage.

Ryan McCuaig
źródło
7
Zwróć uwagę, że jest to rada dotycząca systemu iOS 2.0. Zobacz odpowiedź Rafaela Vegi na temat metod opartych na blokach, jeśli używasz systemu iOS 4.0 lub nowszego.
Ryan McCuaig
Należy również pamiętać, że CoreImage jest teraz dostępny od iOS 5, ale tylko kilka z jego funkcji. Uważam, że można użyć przejścia CoreImage w animacji, ale nie można tworzyć niestandardowych filtrów CoreImage na iOS (5).
Aaron Ash
26

Możemy animować obrazy w iOS 5 za pomocą tego prostego kodu.

CGRect imageFrame = imageView.frame;
imageFrame.origin.y = self.view.bounds.size.height;

[UIView animateWithDuration:0.5
    delay:1.0
    options: UIViewAnimationCurveEaseOut
    animations:^{
        imageView.frame = imageFrame;
    } 
    completion:^(BOOL finished){
        NSLog(@"Done!");
    }];
Guru
źródło
5
jest to również dostępne w iOS 4 i jest określane jako animacja „blokowa”. Nie jest ograniczone do iOS 5 i nowszych.
johnbakers
8

W UIViewDokumentach masz przeczytać o tej funkcji dla iOS4 +

+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion
Chris
źródło
6

W każdym razie metoda „blokowania” jest preferowana teraz-dni. Poniżej wyjaśnię prosty blok.

Rozważ wycięte poniżej. bug2 i bug 3 to imageViews. Poniższa animacja opisuje animację trwającą 1 sekundę z opóźnieniem 1 sekundy. Bug3 został przeniesiony ze środka do środka bug2. Po zakończeniu animacji zostanie zarejestrowana jako „Center Animation Done!”.

-(void)centerAnimation:(id)sender
{
NSLog(@"Center animation triggered!");
CGPoint bug2Center = bug2.center;

[UIView animateWithDuration:1
                      delay:1.0
                    options: UIViewAnimationCurveEaseOut
                 animations:^{
                     bug3.center = bug2Center;
                 } 
                 completion:^(BOOL finished){
                     NSLog(@"Center Animation Done!");
                 }];
}

Mam nadzieję, że to czyste !!!

Deepukjayan
źródło
2
przypisałeś CGPoint bug3.center do bug3Center i zaraz potem przypisałeś CGPoint bug2.center do tej samej zmiennej bug3Center? Dlaczego to robisz ?
pnizzle
ups !! to kumple z literówki. Zaktualizowano teraz.
Deepukjayan
2

Oto animacja Code for Smooth, która może być pomocna dla wielu programistów.
Znalazłem ten fragment kodu z tego samouczka.

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[animation setAutoreverses:YES];
[animation setFromValue:[NSNumber numberWithFloat:1.3f]];
[animation setToValue:[NSNumber numberWithFloat:1.f]];
[animation setDuration:2.f];
[animation setRemovedOnCompletion:NO];

[animation setFillMode:kCAFillModeForwards];
[[self.myView layer] addAnimation:animation forKey:@"scale"];/// add here any Controller that you want t put Smooth animation.
iPatel
źródło
2

spróbujmy i sprawdźmy Swift 3 ...

UIView.transition(with: mysuperview, duration: 0.75, options:UIViewAnimationOptions.transitionFlipFromRight , animations: {
    myview.removeFromSuperview()
}, completion: nil)
Saurabh Sharma
źródło