Как адаптировать интерфейс iOS-приложения для портретной и ландшафтной ориентации?

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

Ответ

Адаптация интерфейса под разные ориентации достигается комбинацией Auto Layout, Size Classes и обработки событий поворота.

Основные подходы:

  1. Auto Layout с приоритетами и активацией/деактивацией: Создавайте гибкие констрейнты. Для разных ориентаций можно активировать один набор констрейнтов и деактивировать другой.

    var portraitConstraints: [NSLayoutConstraint] = []
    var landscapeConstraints: [NSLayoutConstraint] = []
    
    func updateConstraints(for orientation: UIInterfaceOrientation) {
        NSLayoutConstraint.deactivate(landscapeConstraints)
        NSLayoutConstraint.deactivate(portraitConstraints)
    
        if orientation.isLandscape {
            NSLayoutConstraint.activate(landscapeConstraints)
        } else {
            NSLayoutConstraint.activate(portraitConstraints)
        }
    }
  2. Size Classes (Классы размеров): В Interface Builder или коде можно настраивать layout отдельно для комбинаций (compact|regular) x (compact|regular). Например, интерфейс для iPad в regular width x regular height и для iPhone в compact width x regular height.

  3. Обработка поворота в UIViewController: Основной метод для реакции на смену ориентации.

    override func viewWillTransition(to size: CGSize,
                                     with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
    
        coordinator.animate(alongsideTransition: { [weak self] _ in
            // Анимированное обновление layout здесь
            self?.updateLayout(for: size)
        })
    }

Best Practices:

  • Избегайте жестких размеров (frame, константы`). Используйте отношения (multiplier) и приоритеты.
  • Используйте UIStackView. Упрощает создание адаптивных рядов или колонок.
  • Тестируйте на реальных устройствах. Симулятор может не полностью отражать поведение, особенно с клавиатурой или safeAreaInsets.
  • Для кардинально разных layouts рассмотрите возможность использования отдельных .xib/сториборд файлов или даже разных UIViewController.