Почему запуск анимаций интерфейса предпочтительнее в `viewDidAppear`?

«Почему запуск анимаций интерфейса предпочтительнее в `viewDidAppear`?» — вопрос из категории UIKit, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Метод viewDidAppear(_:) — наиболее надежное место для старта анимаций, связанных с layout, по двум основным причинам:

1. Гарантированная готовность layout: К этому моменту представление уже добавлено в иерархию окон, и система отработала все вычисления размеров и позиций (layoutSubviews, viewDidLayoutSubviews). В viewDidLoad или viewWillAppear geometry view может быть еще нулевой или неактуальной.

2. Контроль частоты выполнения: viewDidAppear вызывается один раз при каждом полном появлении экрана на переднем плане. Это предотвращает случайный повторный запуск анимации при возврате с модального экрана или из навигационного стека (в отличие от viewWillAppear, который может вызываться чаще).

Практический пример:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    // К этому моменту self.view.frame и bounds — окончательные.
    UIView.animate(withDuration: 0.5, delay: 0.3, options: .curveEaseOut) {
        self.welcomeLabel.alpha = 1.0
        self.welcomeLabel.center.y -= 20
    }
}

Исключение: Для анимаций, не зависящих от layout (например, fade-in самого view), можно использовать viewWillAppear, установив начальное состояние, а старт — в viewDidAppear.