Когда вызывается метод viewWillAppear у UIViewController?

Ответ

Метод viewWillAppear(_:) вызывается у UIViewController непосредственно перед тем, как его view будет добавлено в иерархию окон и станет видимым пользователю.

Конкретные сценарии вызова:

  1. Первое отображение контроллера (после viewDidLoad и viewWillLayoutSubviews).
  2. Возврат на экран после того, как контроллер был скрыт другим контроллером (например, закрытие модального окна или pop в навигационном стеке).
  3. Смена ориентации устройства (только если контроллер остается активным и видимым).
  4. Восстановление из многозадачности (например, после переключения между приложениями).

Типичное использование:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated) // Важно всегда вызывать super!

    // Обновление данных перед показом
    tableView.reloadData()

    // Настройка навигационной панели
    navigationController?.setNavigationBarHidden(false, animated: animated)

    // Запуск/возобновление анимаций
    startIndicatorAnimation()
}

Отличия от других методов жизненного цикла:

  • viewDidLoad – вызывается один раз после загрузки view в память.
  • viewWillAppear – может вызываться многократно перед каждым появлением view на экране.
  • viewDidAppear – вызывается после того, как view появилось и отрисовалось.

Важно: Не выполняйте в viewWillAppear тяжелые синхронные операции, так как это задержит появление интерфейса.

Ответ 18+ 🔞

Давай разберём эту штуку, которая у всех новичков вызывает лёгкий ступор, а у опытных — нервный тик, если её забыть. viewWillAppear(_:). Ну, метод такой у UIViewController.

Представь себе: твой контроллер — это такой артист за кулисами. viewDidLoad — это когда он пришёл в гримёрку, костюм надел, текст в последний раз пробежал глазами. Всё, готов. Один раз.

А viewWillAppear — это когда ему уже кричат из-за кулис: «Выходи, сука, сейчас тебя на сцену вытолкаем, зрители уже в зале!». И он, этот артист-контроллер, в этот момент может последние штрихи сделать: галстук поправить, микрофон проверить, табличку с данными в телефоне обновить, чтобы не позориться.

Конкретно, когда эта «кричалка» срабатывает:

  1. Самое первое появление. После всех приготовлений (viewDidLoad), но прямо перед тем, как юзеру морду показать.
  2. Возвращение из ссылки. Закрыл модалку, вернулся назад по навигации — опять этот крик: «Выходи, опять ты!».
  3. Телефон повернул. Ориентация сменилась, но контроллер-то на экране остался. Опять надо view подготовить к новым размерам.
  4. Из многозадачности вылез. Свайпнул вверх, потом обратно в апп вернулся — и снова здравствуй, viewWillAppear.

Что в нём обычно творят, чтобы не выглядеть мудаком:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated) // ЭТО, блядь, ОБЯЗАТЕЛЬНО! Не вызвать super — это как выйти на сцену без штанов. Система обидится.

    // Например, обновить таблицу, а то данные могли устареть, пока мы в другом экране шарились.
    tableView.reloadData()

    // Спрятать или показать навигационную панель. А то придёшь, а она не там, где надо.
    navigationController?.setNavigationBarHidden(false, animated: animated)

    // Запустить какую-нибудь крутилку-индикатор, которая на паузе стояла.
    startIndicatorAnimation()
}

Чем не является этот метод, ёпта:

  • Это НЕ viewDidLoad. viewDidLoad — это «один раз надел костюм». viewWillAppear — это «перед каждым выходом на публику поправь костюм». Может вызываться дохуя раз.
  • Это НЕ viewDidAppear. viewWillAppear — это «сейчас выйду». viewDidAppear — это «я вышел, я красавчик, можно поклониться». Всё, что связано с полной отрисовкой и началом взаимодействия — туда.

И главное, нахуй: Не начинай в нём городить овердохуища синхронного кода, который будет всё тормозить. Типа, сетевой запус делать или хуйню в базу грузить. Юзер будет смотреть на пустой экран и думать: «Ну что, блядь, опять зависло?». Всё тяжёлое — либо заранее, либо асинхронно. Этот метод — для быстрых, последних приготовлений.