Ответ
Да, добавлена. К моменту вызова viewWillAppear(_:) корневая view контроллера уже является частью иерархии окон (window и superview назначены). Однако она еще не отрисована на экране.
Последовательность событий при показе UIViewController:
loadView()/viewDidLoad()— создание и первичная настройка view.- Добавление view в иерархию окон (например, при
presentилиpush). viewWillAppear(_:)— view уже в иерархии, но невидима. Идеальное место для синхронизации UI с актуальными данными, запуска подготовительных анимаций или обновления навигационного бара.viewWillLayoutSubviews()/viewDidLayoutSubviews()— расчет лейаута (могут вызываться и раньше).- Отрисовка view на экране.
viewDidAppear(_:)— view полностью видима и отрисована.
Практический пример:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// View уже в иерархии, можно безопасно обращаться к superview
print(view.superview != nil) // true
print(view.window != nil) // true
// Обновляем UI, который мог измениться на другом экране
tableView.reloadData()
// Скрываем/показываем элементы навигации
navigationController?.setNavigationBarHidden(true, animated: animated)
// Запускаем анимацию появления
startInitialAlphaAnimation()
}
Важно: Поскольку viewWillAppear может вызываться многократно (например, при возврате из модального экрана), код в нем должен быть идемпотентным или корректно обрабатывать повторные вызовы.