В каком сценарии вызывается viewWillAppear, но не вызывается viewDidAppear?

Ответ

viewWillAppear(_:) может быть вызван, а viewDidAppear(_:) — нет, если процесс отображения контроллера был прерван до его завершения.

Основные сценарии:

  1. Контроллер удален из иерархии навигации. viewWillAppear сообщает о предстоящем появлении, но если контроллер сразу удалить (например, вернуться назад), viewDidAppear не сработает.

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        print("viewWillAppear вызван")
        // Немедленное удаление контроллера
        navigationController?.popViewController(animated: false)
    }
    // viewDidAppear не будет вызван
  2. Приложение переходит в фоновый режим. Если после viewWillAppear приложение сворачивается (applicationDidEnterBackground), анимация появления прерывается, и viewDidAppear не вызывается.

  3. Появление перекрыто модальным контроллером. Если поверх контроллера, который вот-вот появится, мгновенно отображается модальное окно, его viewDidAppear может не наступить.

Ключевое различие методов:

  • viewWillAppear — уведомление о планируемом появлении view на экране.
  • viewDidAppear — уведомление о фактическом завершении анимации появления и полном отображении view.

Ответ 18+ 🔞

А, слушай, вот тебе классика жанра, про которую все забывают, а потом охуевают, когда их код ведёт себя как последняя мартышлюшка. Представь: viewWillAppear кричит «Я сейчас выйду!», а viewDidAppear молчит как рыба об лёд. И где логика, блядь?

Давай по полочкам, а то мозги набекрень.

Основные сценарии, когда это пиздец случается:

  1. Контроллер выкинули нахуй из стека навигации. Ну вот вызвался viewWillAppear, ты там уже начал что-то настраивать, а тебя взяли и — хоп! — выпилили обратно. viewDidAppear? Не, не слышал.

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        print("А я сейчас появлюсь, ёпта!")
        // А тут тебя сразу в топку
        navigationController?.popViewController(animated: false)
    }
    // И всё. Тишина. viewDidAppear — в рот меня чих-пых.
  2. Приложение схлопнулось в фон. Вызвался viewWillAppear, ты уже предвкушаешь, а тут — бум! — пользователь на Home кнопку нажал или уведомление прилетело. Анимация появления накрылась медным тазом, и viewDidAppear так и остался несбывшейся мечтой.

  3. Сверху мгновенно вылезло модальное окно. Твой контроллер только собрался показаться, а ему на голову тут же сел какой-нибудь алерт или полноэкранная реклама. Всё, приехали. viewDidAppear может и не дождаться своего звёздного часа.

А суть-то, блядь, в чём?

  • viewWillAppear — это как крик «Внимание, я выхожу!». Он про намерение, а не про факт.
  • viewDidAppear — это отчёт «Всё, я на сцене, анимация закончилась, можете аплодировать». Он про свершившееся.

Так что не удивляйся, если твой код в viewDidAppear не сработал. Это не баг, это жизнь, ёпта. Просто система тебе намекает: «Чувак, бля, планировалось одно, а получилось нихуя».