Czy można anulować trwającą UIView
animację? Czy też musiałbym zejść na poziom CA?
tzn. zrobiłem coś takiego (może też ustawiam akcję animacji końcowej):
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties
// set view properties
[UIView commitAnimations];
Ale zanim animacja się zakończy i dostanę zdarzenie zakończenia animacji, chcę je anulować (skrócić to). czy to możliwe? Googlowanie po okolicy powoduje, że kilka osób zadaje to samo pytanie bez odpowiedzi - i jedna lub dwie osoby spekulują, że nie da się tego zrobić.
ios
core-animation
uiviewanimation
philsquared
źródło
źródło
Odpowiedzi:
W ten sposób tworzę nową animację do swojego punktu końcowego. Ustaw bardzo krótki czas trwania i upewnij się, że używasz
+setAnimationBeginsFromCurrentState:
metody, aby zacząć od bieżącego stanu. Po ustawieniu na TAK, bieżąca animacja zostanie skrócona. Wygląda mniej więcej tak:źródło
setAnimationBeginsFromCurrentState:
odradza się korzystanie z iOS 4, ale wciąż tam jest i powinno nadal działać.Posługiwać się:
źródło
Najprostszym sposobem, aby zatrzymać wszystkie animacje na konkretnym zdaniem natychmiast , to:
Połącz projekt z QuartzCore.framework. Na początku kodu:
Teraz, gdy chcesz zatrzymać wszystkie animacje w widoku martwe w ich ścieżkach, powiedz to:
Linia środkowa działałaby sama z siebie, ale opóźnienie runloopa dobiegło końca („moment przerysowania”). Aby zapobiec temu opóźnieniu, zawiń polecenie w jawnym bloku transakcji, jak pokazano. Działa to pod warunkiem, że nie dokonano żadnych innych zmian na tej warstwie w bieżącym runloopie.
źródło
removeAllAnimations
będzie miało efekt uboczny, doprowadzając animację do ostatecznej klatki, zamiast zatrzymywać ją tam, gdzie jest teraz.W systemie iOS 4 i nowszym użyj
UIViewAnimationOptionBeginFromCurrentState
opcji drugiej animacji, aby skrócić pierwszą animację.Jako przykład załóżmy, że masz widok ze wskaźnikiem aktywności. Chcesz zanikać wskaźnik aktywności, gdy zaczyna się aktywność, która może być czasochłonna, i zanikać, gdy aktywność zostanie zakończona. W poniższym kodzie wywoływany jest widok ze wskaźnikiem aktywności
activityView
.źródło
Aby anulować animację, wystarczy ustawić właściwość, która jest obecnie animowana, poza animacją UIView. To zatrzyma animację gdziekolwiek się pojawi, a UIView przejdzie do właśnie zdefiniowanego ustawienia.
źródło
-animationDidStop:finished:context:
. Jeśli[finished boolValue] == NO
, to wiesz, że twoja animacja została jakoś anulowana.Przykro mi, że wskrzesiłem tę odpowiedź, ale w iOS 10 coś się zmieniło, a teraz anulowanie jest możliwe, a nawet możesz z wdziękiem anulować!
Po iOS 10 możesz anulować animacje za pomocą UIViewPropertyAnimator !
Jeśli spełnisz warunek, anuluje animację i zatrzyma się tam, gdzie ją anulowałeś. Metoda zakończenia nie zostanie wywołana. Jeśli jednak zdasz fałsz, jesteś odpowiedzialny za ukończenie animacji:
Możesz zakończyć animację i pozostać w bieżącym stanie (.current) lub przejść do stanu początkowego (.start) lub do stanu końcowego (.end)
Nawiasem mówiąc, możesz nawet zatrzymać i ponownie uruchomić później ...
Uwaga: jeśli nie chcesz nagłego anulowania, możesz cofnąć animację lub nawet zmienić animację po jej wstrzymaniu!
źródło
Jeśli animujesz ograniczenie, zmieniając stałą zamiast właściwości widoku, żadna inna metoda nie działa na iOS 8.
Przykładowa animacja:
Rozwiązanie:
Musisz usunąć animacje z warstw dowolnych widoków, na które wpływa zmiana ograniczenia i ich podwarstw.
źródło
self.constraintView.layer.removeAllAnimations()
Działa także tylko (Swift)Jeśli chcesz po prostu płynnie zatrzymać / zatrzymać animację
Źródło: Jak zatrzymać animację drzewa warstw
źródło
Żadne z powyższych nie rozwiązało tego dla mnie, ale to pomogło:
UIView
animacja ustawia właściwość natychmiast, a następnie animuje. Zatrzymuje animację, gdy warstwa prezentacji pasuje do modelu (właściwość set).Rozwiązałem problem, który brzmiał: „Chcę animować z miejsca, w którym wyglądasz tak, jak wyglądasz” („ty” oznacza widok). Jeśli chcesz, to:
CALayer * pLayer = theView.layer.presentationLayer;
ustaw pozycję na warstwę prezentacji
Korzystam z kilku opcji, w tym
UIViewAnimationOptionOverrideInheritedDuration
Ale ponieważ dokumentacja Apple jest niejasna, nie wiem, czy naprawdę zastępuje inne animacje, gdy są używane, czy po prostu resetuje liczniki.
I na razie powinno to być przyzwoite rozwiązanie.
źródło
źródło
Szybka wersja rozwiązania Stephena Darlington'a
źródło
Mam ten sam problem; interfejsy API nie mają niczego, co by anulowało określoną animację. The
+ (void)setAnimationsEnabled:(BOOL)enabled
wyłącza WSZYSTKIE animacje i dlatego nie działa dla mnie. Istnieją dwa rozwiązania:
1) uczyń z animowanego obiektu widok podrzędny. Następnie, jeśli chcesz anulować animacje dla tego widoku, usuń widok lub ukryj go. Bardzo proste, ale musisz odtworzyć widok cząstkowy bez animacji, jeśli chcesz go wyświetlić.
2) powtórz animację tylko jeden i dokonaj wyboru delegata, aby w razie potrzeby zrestartować animację:
Problem z 2) polega na tym, że zawsze opóźnia się zatrzymanie animacji po zakończeniu bieżącego cyklu animacji.
Mam nadzieję że to pomoże.
źródło
Nawet jeśli anulujesz animację w powyższy sposób, animacja
didStopSelector
nadal działa. Więc jeśli masz stany logiczne w aplikacji sterowane animacjami, będziesz mieć problemy. Z tego powodu w sposób opisany powyżej używam zmiennej kontekstowejUIView
animacji. Jeśli bieżący stan programu zostanie przekazany przez parametr kontekstu do animacji, gdy animacja się zatrzyma,didStopSelector
funkcja może zdecydować, czy powinna coś zrobić, czy po prostu powrócić na podstawie bieżącego stanu i wartości stanu przekazanej jako kontekst.źródło
źródło
Aby wstrzymać animację bez przywracania stanu oryginalnego lub końcowego:
źródło
Kiedy pracuję z
UIStackView
animacją, poza tymremoveAllAnimations()
muszę ustawić niektóre wartości na początkowe, ponieważremoveAllAnimations()
mogę ustawić je na nieprzewidywalny stan. MamstackView
zview1
iview2
wewnątrz, i jeden widok powinien być widoczny i jeden ukryty:źródło
Żadne z odpowiedzi nie zadziałało. Rozwiązałem swoje problemy w ten sposób (nie wiem, czy to poprawny sposób?), Ponieważ miałem problemy z wywołaniem tego zbyt szybko (gdy poprzednia animacja nie była jeszcze ukończona). Mijam pożądaną animację z blokiem customAnim .
źródło