Досліджуючи витік пам'яті, я виявив проблему, пов'язану з технікою виклику setRootViewController:
всередині перехідного анімаційного блоку:
[UIView transitionWithView:self.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{ self.window.rootViewController = newController; }
completion:nil];
Якщо старий контролер подання (замінюваний) в даний час представляє інший контролер перегляду, то наведений вище код не видаляє представлений вигляд з ієрархії подання.
Тобто така послідовність операцій ...
- X стає Root View Controller
- X представляє Y, так що вид Y відображається на екрані
- Використовується
transitionWithView:
для створення Z новим контролером кореневого перегляду
... для користувача виглядає нормально, але інструмент ієрархії вигляду налагодження покаже, що вид Y все ще знаходиться позаду зору Z, всередині a UITransitionView
. Тобто, після трьох кроків вище, ієрархія подання така:
- UIWindow
- UITransitionView
- UIView (погляд Y)
- UIView (подання Z)
- UITransitionView
Я підозрюю, що це проблема, оскільки на момент переходу подання X насправді не є частиною ієрархії подання.
Якщо я відправлю dismissViewControllerAnimated:NO
в X безпосередньо перед цим transitionWithView:
, отримана ієрархія подання:
- UIWindow
- UIView (вид X)
- UIView (подання Z)
Якщо я посилаю dismissViewControllerAnimated:
(ТАК чи НІ) на X, то виконую перехід у completion:
блоці, тоді ієрархія подання є правильною. На жаль, це заважає анімації. Якщо оживляє звільнення, це марно витрачає час; якщо не анімувати, то виглядає зламаним.
Я пробую деякі інші підходи (наприклад, створюю новий клас контролера подання контейнера, який би служив моїм контролером кореневого перегляду), але не знайшов нічого, що працює. Я буду оновлювати це питання, коли ходжу.
Кінцевою метою є перехід від представленого подання до нового контролера кореневого перегляду безпосередньо, не залишаючи ієрархічних поглядів навколо.
UIWindow
не потрібно робити обмін , але не було часу багато експериментувати.