В каком порядке вызываются методы appearance при пуше UIViewController в UINavigationController
Что проверяют
Знаете ли вы жизненный цикл контроллера не списком методов, а в связке двух экранов: что происходит с тем, кто уходит, и с тем, кто приходит. Следом часто спрашивают про свайп назад, который пользователь бросил на середине.
Как отвечать
Пусть в стеке лежит A, и вы вызываете pushViewController(B, animated: true). Порядок такой:
B.viewDidLoad(): если view уBещё не загружено. Вызывается один раз за жизнь view, а не при каждом показе;A.viewWillDisappear(_:);B.viewWillAppear(_:): view ещё не в иерархии окна, размеры могут быть не финальными;B.viewIsAppearing(_:): появился в SDK iOS 17 и работает начиная с iOS 13. View уже в иерархии, trait collection и размеры известны, это правильное место для настройки, зависящей от геометрии;- анимация перехода, по ходу которой идут
viewWillLayoutSubviewsиviewDidLayoutSubviews; A.viewDidDisappear(_:);B.viewDidAppear(_:).
То есть «will» уходящего экрана идёт раньше «will» приходящего, а «did» уходящего раньше «did» приходящего. Порядок вызовов между двумя разными контроллерами Apple не описывает как контракт, поэтому строить логику, которая на него опирается, не стоит.
Чтобы отличить первый показ от возврата назад, используют isMovingToParent в viewWillAppear и isMovingFromParent в viewWillDisappear. Для действий синхронно с анимацией есть transitionCoordinator и animate(alongsideTransition:completion:).
Где спотыкаются
Ставят viewDidLoad после viewWillAppear или считают, что он вызывается при каждом показе. Загрузка view происходит один раз, до первого появления.
Считают, что за «will» всегда следует «did». При интерактивном свайпе назад, который пользователь отменил, viewWillAppear у нижнего экрана уже вызван, а viewDidAppear так и не придёт. Проверяйте context.isCancelled в completion координатора.
Делают тяжёлую работу, например сетевой запрос, в viewWillAppear без защиты от повторов. Метод срабатывает при каждом возврате на экран, в том числе после закрытия модального окна в полноэкранном стиле.