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.