Mam aplikację do nawigacji i chcę zmienić animację animacji push i pop. Jak mam to zrobić?
Edytuj 2018
Odpowiedzi na to pytanie było wiele i minęło trochę czasu. Ponownie wybrałem odpowiedź na to, co uważam za najbardziej aktualne. Jeśli jest ktoś, kto myśli inaczej, daj mi znać w komentarzach
ios
animation
uinavigationcontroller
Ukłucie
źródło
źródło
Odpowiedzi:
Na rok 2019 „ostateczna odpowiedź!”
Preambuła:
Powiedz, że jesteś nowy w tworzeniu iOS. Mylące jest to, że Apple zapewnia dwa przejścia, z których można łatwo korzystać. Są to: „crossfade” i „flip”.
Ale oczywiście „crossfade” i „flip” są bezużyteczne. Nigdy nie są używane. Nikt nie wie, dlaczego Apple zapewnił te dwa bezużyteczne przejścia!
Więc:
Powiedz, że chcesz wykonać zwykłe, wspólne przejście, takie jak „slajd”. W takim przypadku musisz wykonać OGROMNĄ pracę! .
Ta praca została wyjaśniona w tym poście.
Wystarczy powtórzyć:
Zaskakujące: jeśli masz iOS, jeśli chcesz najprostszych, najczęstszych codziennych przejść (takich jak zwykły slajd), musisz wykonać całą pracę związaną z implementacją pełnego niestandardowego przejścia .
Oto jak to zrobić ...
1. Potrzebujesz niestandardowego
UIViewControllerAnimatedTransitioning
Potrzebujesz własnego bool
popStyle
. (Czy wyskakuje, czy wyskakuje?)Musisz dołączyć
transitionDuration
(trywialne) i główne połączenie,animateTransition
W rzeczywistości musisz napisać dwie różne procedury dla wnętrza
animateTransition
. Jeden dla popychacza i jeden dla popu. Prawdopodobnie nazwij jeanimatePush
ianimatePop
. W środkuanimateTransition
po prostu przejdźpopStyle
do dwóch procedurPoniższy przykład przedstawia proste przeniesienie / przeniesienie
W twoim
animatePush
ianimatePop
rutynie. Państwo musi uzyskać „z widoku” i „do widzenia”. (Jak to zrobić, pokazano w przykładzie kodu.)i musi
addSubview
za nowy „do” widzenia.i musisz zadzwonić
completeTransition
pod koniec swojego animeWięc ..
I wtedy ...
2. Użyj go w kontrolerze widoku.
Uwaga: co dziwne, musisz to zrobić tylko w „pierwszym” kontrolerze widoku. (Ten, który jest „pod spodem”).
Z tym, który wyskakujesz na wierzch , nic nie rób . Łatwo.
Twoja klasa ...
staje się...
Otóż to.
Naciśnij i pop dokładnie tak, jak zwykle, bez zmian. Popychać ...
i żeby to pop, możesz, jeśli chcesz, po prostu zrób to na następnym ekranie:
Uff
3. Skorzystaj również z innych odpowiedzi na tej stronie, które wyjaśniają, jak zastąpić AnimatedTransitioning
Przewiń do @AlanZeino i @elias, aby uzyskać więcej dyskusji na temat tego, jak
AnimatedTransitioning
w aplikacjach na iOS w dzisiejszych czasach!źródło
animatePush
ianimatePop
to są dwa różne kierunki!Zrobiłem następujące i działa dobrze .. i jest prosty i łatwy do zrozumienia ..
I to samo dotyczy push…
Wersja Swift 3.0:
źródło
Animated:NO
część jest niezbędna. JeśliYES
zostanie przekazany, animacje mieszają się i powodują śmieszne efekty.setViewControllers:
W ten sposób zawsze udało mi się wykonać to zadanie.
Dla Push:
Dla popu:
Nadal otrzymuję wiele opinii, więc zamierzam go zaktualizować, aby używać bloków animacji, co jest zalecanym przez Apple sposobem robienia animacji.
Dla Push:
Dla popu:
źródło
super
przezself.navigationController
UIViewController
nazwę bez części „ViewController”. Ta nazwa jest bardziej odpowiednia dla UIView.do pchnięcia
dla popu
źródło
@Magnus odpowiedź, tylko wtedy dla Swift (2.0)
Niektóre sidenotes:
Możesz to zrobić również za pomocą Segue, po prostu zaimplementuj to w
prepareForSegue
lubshouldPerformSegueWithIdentifier
. Zachowa to jednak również domyślną animację. Aby to naprawić, musisz przejść do scenorysu, kliknąć Segue i odznaczyć pole „Animacje”. Ale to ograniczy twoją aplikację dla IOS 9.0 i nowszych (przynajmniej kiedy zrobiłem to w Xcode 7).Robiąc w segue, ostatnie dwa wiersze należy zastąpić:
Mimo że ustawiłem fałsz, to w pewnym sensie to ignoruje.
źródło
Pamiętaj, że w Swift , rozszerzenie są zdecydowanie znajomych!
źródło
Korzystanie z połączeń prywatnych jest złym pomysłem, ponieważ Apple nie zatwierdza już aplikacji, które to robią. Może mógłbyś spróbować:
źródło
-pushViewController:transition:forceImmediate:
co byłoby złym pomysłem.Ponieważ jest to najlepszy wynik w Google, pomyślałem, że podzielę się tym, co uważam za najbardziej rozsądny sposób; który ma używać przejściowego interfejsu API systemu iOS 7+. Zaimplementowałem to dla iOS 10 z Swift 3.
Całkiem łatwo jest połączyć to z
UINavigationController
animacją między dwoma kontrolerami widoku, jeśli utworzysz podklasęUINavigationController
i zwrócisz instancję klasy zgodnej zUIViewControllerAnimatedTransitioning
protokołem.Na przykład tutaj jest moja
UINavigationController
podklasa:Widać, że ustawiłem wartość
UINavigationControllerDelegate
samą w sobie, a w rozszerzeniu mojej podklasy zaimplementowałem metodę,UINavigationControllerDelegate
która umożliwia zwrócenie niestandardowego kontrolera animacji (tjNavigationControllerAnimation
.). Ten niestandardowy kontroler animacji zastąpi dla ciebie standardową animację.Prawdopodobnie zastanawiasz się, dlaczego przekazuję operację do
NavigationControllerAnimation
instancji za pomocą jej inicjatora. Robię to, aby przyNavigationControllerAnimation
implementacjiUIViewControllerAnimatedTransitioning
protokołu wiedziałem, co to jest operacja (tj. „Push” lub „pop”). Pomaga to wiedzieć, jaki rodzaj animacji powinienem zrobić. W większości przypadków chcesz wykonać inną animację w zależności od operacji.Reszta jest dość standardowa. Zaimplementuj dwie wymagane funkcje w
UIViewControllerAnimatedTransitioning
protokole i animuj, jak chcesz:Ważne jest, aby pamiętać, że dla każdego rodzaju operacji (np. „Push” lub „pop”) kontrolery widoku i od będą różne. Podczas operacji wypychania kontroler to view zostanie wypchnięty. Podczas operacji pop kontroler do widoku będzie tym, który jest przenoszony, a kontroler z widoku będzie tym, który jest otwierany.
Ponadto
to
kontroler widoku należy dodać jako widok podrzędnycontainerView
w kontekście przejścia.Po zakończeniu animacji musisz zadzwonić
transitionContext.completeTransition(true)
. Jeśli robisz interaktywną przejścia, trzeba będzie dynamicznie zwróciBool
sięcompleteTransition(didComplete: Bool)
, w zależności czy przejście jest zakończona pod koniec animacji.Na koniec ( czytanie opcjonalne ) możesz zobaczyć, jak wykonałem przejście, nad którym pracowałem. Ten kod jest nieco bardziej zhackowany i napisałem go dość szybko, więc nie powiedziałbym, że to świetny kod animacji, ale wciąż pokazuje, jak wykonać część animacji.
Moje było naprawdę prostym przejściem; Chciałem naśladować tę samą animację, którą zwykle robi UINavigationController, ale zamiast animacji „następna strona powyżej”, chciałem zaimplementować animację 1: 1 starego kontrolera widoku w tym samym czasie, co nowy widok pojawia się kontroler. Powoduje to, że dwa kontrolery widoku wyglądają tak, jakby były ze sobą połączone.
W przypadku operacji wypychania, która wymaga najpierw ustawienia początku
toViewController
widoku na ekranie poza osią x, dodania go jako widoku podrzędnegocontainerView
i animowania go na ekranie poprzez ustawienie goorigin.x
na zero. Jednocześnie animujęfromViewController
widok, odsuwając goorigin.x
od ekranu:Operacja pop jest w zasadzie odwrotna. Dodaj
toViewController
widok podrzędnycontainerView
i animuj odfromViewController
prawej, animująctoViewController
od lewej:Oto sedno z całym szybkim plikiem:
https://gist.github.com/alanzeino/603293f9da5cd0b7f6b60dc20bc766be
źródło
Tam są UINavigationControllerDelegate i UIViewControllerAnimatedTransitioning tam możesz zmienić animację na cokolwiek chcesz.
Na przykład jest to pionowa animacja pop dla VC:
}
I wtedy
Przydatny samouczek https://www.objc.io/issues/5-ios7/view-controller-transitions/
źródło
Na podstawie odpowiedzi zaktualizowanej do szybkiego 4
jordanperry
Do pchania
UIViewController
Dla popu
źródło
Oto jak zrobiłem to samo w Swift:
Dla Push:
Dla popu:
Zrobiłem to trochę inaczej niż niektóre z powyższych odpowiedzi - ale ponieważ jestem nowy w rozwoju Swift, może to nie być właściwe. Zastąpiłem
viewWillDisappear:animated:
i dodałem tam kod pop:źródło
Odpowiedź Lucy Davanzo w Swift 4.2
źródło
Niedawno próbowałem zrobić coś podobnego. Uznałem, że nie podoba mi się przesuwana animacja UINavigationController, ale nie chciałem też wykonywać animacji, które UIView daje ci curl lub coś w tym rodzaju. Chciałem zrobić przenikanie między widokami, kiedy naciskam lub pop.
Problem polega na tym, że widok dosłownie usuwa widok lub przesuwa go nad bieżącym, więc zanikanie nie działa. Rozwiązanie, na które wpadłem, polegało na wzięciu mojego nowego widoku i dodaniu go jako widoku podrzędnego do bieżącego widoku z góry na stosie UIViewController. Dodaję go z cyfrą 0, a następnie przechodzę w płynne przejście. Kiedy sekwencja animacji zakończy się, pcham widok na stos bez animowania go. Następnie wracam do starego topView i sprzątam rzeczy, które zmieniłem.
Jest to trochę bardziej skomplikowane, ponieważ masz elementy nawigacyjne, które musisz dostosować, aby przejście wyglądało poprawnie. Ponadto, jeśli wykonujesz obrót, musisz dostosować rozmiary ramek, dodając widoki jako widoki podrzędne, aby były poprawnie wyświetlane na ekranie. Oto część kodu, którego użyłem. Podklasowałem UINavigationController i zastąpiłem metody push i pop.
Jak wspomniałem w kodzie, zawsze mam element przycisku lewego paska, więc nie sprawdzam, czy nie ma go przed umieszczeniem go w tablicy, którą przekazuję jako kontekst dla delegata animacji. Jeśli to zrobisz, możesz to sprawdzić.
Problem, który znalazłem, polegał na tym, że awaria metody delegowania nie spowoduje awarii programu. To po prostu powstrzymuje delegata przed ukończeniem, ale nie pojawia się żadne ostrzeżenie.
Ponieważ więc przeprowadzałem czyszczenie w ramach tej procedury delegowania, powodowało to dziwne zachowanie wizualne, ponieważ nie kończyło czyszczenia.
Przycisk Wstecz, który tworzę, wywołuje metodę „goBack”, a ta metoda po prostu wywołuje procedurę pop.
Oto moja popowa rutyna.
To prawie wszystko. Będziesz potrzebować dodatkowego kodu, jeśli chcesz zastosować rotacje. Musisz ustawić rozmiar ramki swoich widoków, które dodajesz jako widoki podrzędne, zanim je pokażesz, w przeciwnym razie napotkasz problemy z orientacją poziomą, ale ostatnim razem, gdy widziałeś poprzedni widok, był portret. Więc dodajesz go jako widok pomocniczy i przenikasz, ale pokazuje się on jako portret, a potem, gdy pop bez animacji, ten sam widok, ale ten, który jest na stosie, teraz jest poziomy. Całość wygląda trochę funky. Implementacja rotacji dla każdego jest trochę inna, więc nie dodałem tutaj mojego kodu.
Mam nadzieję, że to pomaga niektórym ludziom. Szukałem czegoś takiego i nie mogłem nic znaleźć. Nie sądzę, że to idealna odpowiedź, ale w tym momencie działa dla mnie naprawdę dobrze.
źródło
Możesz teraz użyć
UIView.transition
. Zauważ, żeanimated:false
. Działa to z dowolną opcją przejścia, pop, push lub zamianą stosu.źródło
Korzystając z odpowiedzi iJordan jako inspiracji, dlaczego po prostu nie utworzyć kategorii na UINavigationController do użycia w całej aplikacji zamiast kopiować / wklejać ten kod animacji w dowolnym miejscu?
UINavigationController + Animation.h
UINavigationController + Animation.m
Następnie wystarczy zaimportować plik UINavigationController + Animation.h i wywołać go normalnie:
źródło
To jest bardzo proste
źródło
Spójrz na ADTransitionController , spadek w zastępstwie UINavigationController z niestandardowymi animacjami przejścia (jego interfejs API pasuje do interfejsu API UINavigationController), który stworzyliśmy w Applidium.
Możesz używać różnych predefiniowanych animacji dla akcji push i pop, takich jak Swipe , Fade , Cube , Carrousel , Zoom i tak dalej.
źródło
Chociaż wszystkie odpowiedzi tutaj są świetne, a większość działa bardzo dobrze, istnieje nieco prostsza metoda, która osiąga ten sam efekt ...
Dla Push:
Dla popu:
źródło
Nie wiem, w jaki sposób możesz publicznie zmienić animację przejścia.
Jeśli przycisk „wstecz” nie jest konieczny, należy użyć modalnych kontrolerów widoku, aby uzyskać przejścia „push from bottom” / „flip” / „fade” / (≥3,2) „zawinięcie strony”.
Po stronie prywatnej metoda
-pushViewController:animated:
wywołuje metodę nieudokumentowaną-pushViewController:transition:forceImmediate:
, więc np. Jeśli chcesz przejść z przejścia z lewej na prawą, możesz użyćNie można jednak zmienić przejścia „pop” w ten sposób.
źródło
Zobacz moją odpowiedź na to pytanie, aby dowiedzieć się, jak to zrobić w znacznie mniejszej liczbie wierszy kodu. Ta metoda pozwala animować pseudo „Push” nowego kontrolera widoku w dowolny sposób, a gdy animacja jest zakończona, konfiguruje kontroler nawigacji tak, jakbyś użył standardowej metody Push. Mój przykład pozwala animować wsuwanie z lewej lub z prawej strony. Kod powtórzony tutaj dla wygody:
źródło
W przykładowej aplikacji sprawdź tę odmianę. https://github.com/mpospese/MPFoldTransition/
źródło
Po prostu użyj:
źródło
Uświadomienie sobie tego jest starym pytaniem. Nadal chciałbym opublikować tę odpowiedź, ponieważ miałem pewne problemy
viewControllers
z kilkoma proponowanymi odpowiedziami. Moim rozwiązaniem jest podklasowanieUINavigationController
i zastępowanie wszystkich metod pop i push.FlippingNavigationController.h
FlippingNavigationController.m:
źródło
Wiem, że ten wątek jest stary, ale pomyślałem, że wpłacę dwa centy. Nie musisz tworzyć niestandardowej animacji, istnieje prosty (może hacky) sposób na zrobienie tego. Zamiast używać wypychania, utwórz nowy kontroler nawigacyjny, ustaw nowy kontroler widoku jako główny kontroler widoku tego kontrolera nawigacyjnego, a następnie zaprezentuj kontroler nawigacyjny z oryginalnego kontrolera nawigacyjnego. Prezent można łatwo dostosować za pomocą wielu stylów i nie trzeba tworzyć niestandardowej animacji.
Na przykład:
I możesz zmienić styl prezentacji, jak chcesz.
źródło
Znalazłem lekko rekurencyjny sposób na zrobienie tego, co działa dla moich celów. Mam zmienną instancji BOOL, której używam do blokowania normalnej animacji popping i zastępowania własnej nie-animowanej wiadomości pop. Zmienna jest początkowo ustawiona na NIE. Po naciśnięciu przycisku Wstecz metoda delegowania ustawia go na TAK i wysyła nową nie animowaną wiadomość pop na pasek nawigacyjny, w ten sposób ponownie wywołując tę samą metodę delegowania, tym razem ze zmienną ustawioną na TAK. Gdy zmienna jest ustawiona na TAK, metoda delegowania ustawia ją na NIE i zwraca TAK, aby umożliwić wystąpienie nie animowanego popu. Po powrocie drugiego połączenia delegata wracamy do pierwszego, gdzie zwracane jest NIE, blokując oryginalny animowany pop! W rzeczywistości nie jest tak niechlujny jak się wydaje. Moja metoda powinna powinna wyglądać następująco:
Pracuje dla mnie.
źródło