← Назад к вопросам
В каком методе можно отследить поворот экрана?
1.6 Junior🔥 242 комментариев
#UIKit и верстка
Комментарии (2)
🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Методы отслеживания поворота экрана в iOS
В iOS разработке существует несколько основных подходов для отслеживания изменения ориентации устройства. Вот ключевые методы и best practices:
1. ViewController Lifecycle Methods
Наиболее распространенный способ — использование методов жизненного цикла UIViewController:
class ViewController: UIViewController {
// Вызывается перед изменением размеров вью
override func viewWillTransition(to size: CGSize,
with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { context in
// Анимация во время поворота
if UIDevice.current.orientation.isLandscape {
print("Устройство переходит в альбомную ориентацию")
} else {
print("Устройство переходит в портретную ориентацию")
}
}, completion: { context in
// Действия после завершения поворота
print("Поворот завершен")
})
}
// Вызывается при изменении размеров вью
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if traitCollection.verticalSizeClass == .compact {
// Компактная высота (обычно альбомный режим)
} else {
// Обычная высота (обычно портретный режим)
}
}
}
2. Trait Collection Changes
Использование UITraitCollection для отслеживания изменений характеристик устройства:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if traitCollection.horizontalSizeClass != previousTraitCollection?.horizontalSizeClass ||
traitCollection.verticalSizeClass != previousTraitCollection?.verticalSizeClass {
print("Изменение size class:")
print("Горизонтальный: \(traitCollection.horizontalSizeClass == .compact ? "compact" : "regular")")
print("Вертикальный: \(traitCollection.verticalSizeClass == .compact ? "compact" : "regular")")
}
}
3. Notification Center
Подписка на системные уведомления об изменении ориентации:
class OrientationObserver {
init() {
NotificationCenter.default.addObserver(
self,
selector: #selector(orientationDidChange),
name: UIDevice.orientationDidChangeNotification,
object: nil
)
// Включаем генерацию событий поворота
UIDevice.current.beginGeneratingDeviceOrientationNotifications()
}
@objc func orientationDidChange() {
let orientation = UIDevice.current.orientation
switch orientation {
case .portrait:
print("Портретная ориентация")
case .portraitUpsideDown:
print("Портретная ориентация (перевернутая)")
case .landscapeLeft:
print("Альбомная ориентация (влево)")
case .landscapeRight:
print("Альбомная ориентация (вправо)")
case .faceUp, .faceDown:
print("Устройство лежит лицом вверх/вниз")
default:
print("Неизвестная ориентация")
}
}
deinit {
NotificationCenter.default.removeObserver(self)
UIDevice.current.endGeneratingDeviceOrientationNotifications()
}
}
4. Современный подход (iOS 16+)
В iOS 16 появились новые API для работы с ориентацией:
// В SceneDelegate для поддержки различных ориентаций
func application(_ application: UIApplication,
supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return [.portrait, .landscape]
}
// Использование responsive layouts с Size Classes
func configureLayoutForCurrentOrientation() {
let isLandscape = UIDevice.current.orientation.isLandscape
let isPortrait = UIDevice.current.orientation.isPortrait
if isLandscape {
applyLandscapeLayout()
} else if isPortrait {
applyPortraitLayout()
}
}
5. Key Considerations
- Разница между device orientation и interface orientation:
UIDeviceOrientationотносится к физическому положению устройства, аUIInterfaceOrientation— к ориентации интерфейса. - Поддержка нескольких ориентаций: настройка в Info.plist или через
supportedInterfaceOrientations - Автоматический layout: использование Auto Layout с constraints, которые адаптируются к изменениям
- Size Classes: предпочтительный способ создания адаптивных интерфейсов
- Безопасные области: учет
safeAreaInsetsпри изменении ориентации
Best Practices
- Используйте Auto Layout для автоматической адаптации интерфейса
- Тестируйте на реальных устройствах, так как симулятор может не полностью воспроизводить поведение
- Учитывайте разные размеры экрана (iPhone, iPad, Split View)
- Избегайте жестких размеров в пользу адаптивных решений
- Для сложных переходов используйте
UIViewControllerTransitionCoordinator
Наиболее правильным подходом считается использование комбинации Auto Layout, Size Classes и метода viewWillTransition(to:with:), что обеспечивает наиболее гибкую и предсказуемую адаптацию интерфейса к изменениям ориентации устройства.