Ответ
Адаптация интерфейса под разные ориентации достигается комбинацией Auto Layout, Size Classes и обработки событий поворота.
Основные подходы:
-
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) } } -
Size Classes (Классы размеров): В Interface Builder или коде можно настраивать layout отдельно для комбинаций
(compact|regular) x (compact|regular). Например, интерфейс для iPad вregular width x regular heightи для iPhone вcompact width x regular height. -
Обработка поворота в 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.