Badając wyciek pamięci, odkryłem problem związany z techniką wywoływania setRootViewController:
wewnątrz bloku animacji przejścia:
[UIView transitionWithView:self.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{ self.window.rootViewController = newController; }
completion:nil];
Jeśli stary kontroler widoku (zastępowany) aktualnie prezentuje inny kontroler widoku, to powyższy kod nie usuwa prezentowanego widoku z hierarchii widoków.
Oznacza to, że ta sekwencja operacji ...
- X staje się głównym kontrolerem widoku
- X przedstawia Y, więc widok Y jest na ekranie
- Użycie
transitionWithView:
do uczynienia Z nowego głównego kontrolera widoku
... wygląda dobrze dla użytkownika, ale narzędzie Debug View Hierarchy ujawni, że widok Y nadal znajduje się za widokiem Z, wewnątrz a UITransitionView
. Oznacza to, że po wykonaniu trzech powyższych kroków hierarchia widoków wygląda następująco:
- UIWindow
- UITransitionView
- UIView (widok Y)
- UIView (widok Z)
- UITransitionView
Podejrzewam, że jest to problem, ponieważ w momencie przejścia widok X nie jest w rzeczywistości częścią hierarchii widoków.
Jeśli wyślę dismissViewControllerAnimated:NO
do X bezpośrednio wcześniej transitionWithView:
, wynikowa hierarchia widoków jest następująca:
- UIWindow
- UIView (widok X)
- UIView (widok Z)
Jeśli wyślę dismissViewControllerAnimated:
(TAK lub NIE) do X, a następnie wykonam przejście w completion:
bloku, to hierarchia widoków jest poprawna. Niestety to przeszkadza w animacji. Jeśli animujesz zwolnienie, marnuje czas; jeśli nie jest animowany, wygląda na zepsuty.
Próbuję innych podejść (np. Tworząc nową klasę kontrolera widoku kontenera, która będzie służyć jako mój główny kontroler widoku), ale nie znalazłem niczego, co działa. Zaktualizuję to pytanie na bieżąco.
Ostatecznym celem jest bezpośrednie przejście z przedstawionego widoku do nowego głównego kontrolera widoku, bez pozostawiania zbłąkanych hierarchii widoków.
UIWindow
jest rzeczą do zrobienia, ale nie miałem czasu na wiele eksperymentów.Odpowiedzi:
Niedawno miałem podobny problem. Musiałem ręcznie usunąć to
UITransitionView
z okna, aby naprawić problem, a następnie wywołać odrzucenie na poprzednim kontrolerze widoku głównego, aby upewnić się, że został zwolniony.Poprawka nie jest zbyt przyjemna, ale jeśli nie znalazłeś lepszego sposobu od czasu wysłania pytania, to jedyna rzecz, którą znalazłem, która działa!
viewController
to tylkonewController
z twojego pierwotnego pytania.Mam nadzieję, że to również pomoże ci rozwiązać twój problem, to absolutny ból w dupie!
(Zobacz historię edycji innych wersji Swift)
Dla ładniejszej implementacji jako rozszerzenia
UIWindow
umożliwiającego przekazanie opcjonalnego przejścia.Stosowanie:
Lub
źródło
UITransitionView
w Twojej aplikacji, która jest wtedy pobierana jako część symboli aplikacji, które, jak sądzę, używa App Store do sprawdzenia.Zmierzyłem się z tym problemem i denerwował mnie przez cały dzień. Wypróbowałem rozwiązanie obj-c @ Richa i okazuje się, że kiedy chcę przedstawić inny viewController po tym, zostanie zablokowany pustym UITransitionView.
W końcu doszedłem do tego w jaki sposób i to zadziałało.
W porządku, teraz wszystko, co musisz zrobić, to zadzwonić,
[self setRootViewController:newViewController];
gdy chcesz przełączyć kontroler widoku głównego.źródło
dismissViewControllerAnimated:
wyglądu może być nieco lepsze niż brak animacji.UITransitionView
Jednak unika duchów w hierarchii widoku.Próbuję prostej rzeczy, która działa dla mnie na iOs 9.3: po prostu usuń stary widok ViewControllera z jego hierarchii podczas
dismissViewControllerAnimated
kończenia pracy.Popracujmy nad widokiem X, Y i Z, jak wyjaśniono w benzado :
Które dają:
W moim przypadku X i Y są dobrze zwolnione, a ich widok nie jest już w hierarchii!
źródło
Miałem podobny problem. W moim przypadku miałem hierarchię viewController, a jeden z podrzędnych kontrolerów widoku miał przedstawiony kontroler widoku. Kiedy zmieniłem wtedy kontroler widoku głównego systemu Windows, z jakiegoś powodu prezentowany kontroler widoku wciąż był w pamięci. Tak więc rozwiązaniem było odrzucenie wszystkich kontrolerów widoku przed zmianą kontrolera widoku głównego systemu Windows.
źródło
Do tego problemu doszedłem używając tego kodu:
Wyłączenie tego kodu rozwiązało problem. Udało mi się to uruchomić, włączając animację przejścia tylko wtedy, gdy pasek filtru, który jest animowany, jest inicjowany.
Tak naprawdę nie jest to odpowiedź, której szukasz, ale może przynieść ci właściwą podkładkę do znalezienia rozwiązania.
źródło