Как анимировать изменения интерфейса при смене ориентации экрана в iOS?

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

Ответ

Для плавной анимации изменений layout при повороте устройства используйте UIViewControllerTransitionCoordinator, доступный в методе viewWillTransition(to:with:).

Стандартный подход:

override func viewWillTransition(to size: CGSize,
                               with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    // Сообщаем системе, что мы хотим выполнить анимацию вместе с системной анимацией поворота
    coordinator.animate(alongsideTransition: { [weak self] context in
        guard let self = self else { return }
        // 1. Применяем изменения constraints (если используете Auto Layout)
        self.updateConstraintsForOrientation()
        // 2. Принудительно обновляем layout внутри анимационного блока
        self.view.layoutIfNeeded()
        // 3. Можем анимировать другие свойства (альфа, трансформацию)
        self.headerView.alpha = (size.width > size.height) ? 0.8 : 1.0
    }, completion: { [weak self] context in
        // Действия после завершения системной анимации
        if context.isCancelled {
            print("Поворот отменен")
        } else {
            self?.finalizeLayoutAfterRotation()
        }
    })
}

Best practices и пояснения:

  1. coordinator.animate(alongsideTransition:) — ключевой метод. Он синхронизирует вашу анимацию с системной.
  2. layoutIfNeeded() — обязательный вызов внутри блока анимации, чтобы изменения, вызванные активацией/деактивацией constraints или изменением frame, были анимированы.
  3. Захват [weak self] — критически важен для предотвращения retain cycles, так как coordinator может удерживать блок до завершения анимации.
  4. Анимация через Auto Layout: Изменяйте constant у constraints или активируйте/деактивируйте наборы constraints, затем вызывайте layoutIfNeeded().
  5. Проверка isCancelled в completion — пользователь мог начать обратный поворот до завершения первой анимации.

Альтернатива для простых случаев: Если нужно лишь плавно обновить frame при повороте, убедитесь, что у вашего UIView установлено свойство autoresizingMask или используются корректные constraints — система анимирует это автоматически.