При исследовании утечки памяти я обнаружил проблему, связанную с техникой вызова 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 новым контроллером корневого представления
... выглядит нормально для пользователя, но инструмент Debug View Hierarchy покажет, что представление Y все еще находится за представлением Z, внутри UITransitionView
. То есть после трех шагов, описанных выше, иерархия представлений будет следующей:
- UIWindow
- UITransitionView
- UIView (взгляд Y)
- UIView (взгляд Z)
- UITransitionView
Я подозреваю, что это проблема, потому что во время перехода представление X фактически не является частью иерархии представлений.
Если я отправлю dismissViewControllerAnimated:NO
X непосредственно перед этим transitionWithView:
, результирующая иерархия представлений будет:
- UIWindow
- UIView (взгляд X)
- UIView (взгляд Z)
Если я отправлю dismissViewControllerAnimated:
(ДА или НЕТ) в X, а затем выполню переход в completion:
блоке, тогда иерархия представлений верна. К сожалению, это мешает анимации. Анимация увольнения - пустая трата времени; если не анимировать, он выглядит сломанным.
Я пробую другие подходы (например, создание нового класса контроллера представления контейнера в качестве моего корневого контроллера представления), но не нашел ничего, что работает. Я буду обновлять этот вопрос по мере поступления.
Конечная цель - напрямую перейти от представленного представления к новому контроллеру корневого представления, не оставляя ненужных иерархий представлений.
UIWindow
стоит ли менять местами , но у меня не было времени на эксперименты.Ответы:
Недавно у меня была похожая проблема. Мне пришлось вручную удалить это
UITransitionView
из окна, чтобы решить проблему, а затем вызвать отклонение на предыдущем контроллере корневого представления, чтобы убедиться, что он освобожден.Исправление на самом деле не очень хорошее, но если вы не нашли лучший способ с момента публикации вопроса, это единственное, что я нашел работающим!
viewController
это простоnewController
из вашего исходного вопроса.Я надеюсь, что это поможет вам решить и вашу проблему, это абсолютная заноза в заднице!
(См. Историю изменений для других версий Swift)
Для более удобной реализации в качестве расширения,
UIWindow
позволяющего передавать необязательный переход.Использование:
Или
источник
UITransitionView
в вашем приложении, как тогда, который был выбран как часть символов приложения, которые, я думаю, App Store использует для проверки.Я столкнулся с этой проблемой, и она меня раздражала целый день. Я пробовал решение obj-c @ Rich, и оказалось, что когда я хочу представить еще один viewController после этого, я буду заблокирован пустым UITransitionView.
Наконец, я понял, что это сработало для меня.
Хорошо, теперь все, что вам нужно сделать, это вызвать,
[self setRootViewController:newViewController];
когда вы хотите переключить контроллер корневого представления.источник
dismissViewControllerAnimated:
Возможно, анимация внешнего вида немного лучше, чем отсутствие анимации.UITransitionView
Тем не менее, избегает призраков в иерархии представлений.Я пробую простую вещь, которая работает для меня на iOs 9.3: просто удалите старое представление viewController из его иерархии во время
dismissViewControllerAnimated
завершения.Давайте работать с представлениями X, Y и Z, как объяснил benzado :
Которые дают:
В моем случае X и Y хорошо освобождены, и их представление больше не находится в иерархии!
источник
Была аналогичная проблема. В моем случае у меня была иерархия viewController, и один из дочерних контроллеров представления имел представленный контроллер представления. Когда я изменил контроллер корневого представления Windows, по какой-то причине представленный контроллер представления все еще находился в памяти. Итак, решение заключалось в том, чтобы закрыть все контроллеры представления, прежде чем я изменю контроллер корневого представления Windows.
источник
Я столкнулся с этой проблемой при использовании этого кода:
Отключение этого кода решило проблему. Мне удалось заставить это работать, включив эту анимацию перехода только при инициализации анимированной панели фильтров.
На самом деле это не тот ответ, который вы ищете, но он может подвести вас к правильному пути для поиска решения.
источник