Все может стать довольно запутанным, когда у вас сложная иерархия представлений, например, наличие нескольких контроллеров навигации и / или контроллеров представления вкладок.
Эта реализация помещает его в отдельные контроллеры представления, чтобы установить, когда они хотели бы заблокировать ориентацию, вместо того, чтобы полагаться на делегата приложения, чтобы найти их путем итерации по вложенным представлениям.
Свифт 3, 4, 5
В AppDelegate:
var orientationLock = UIInterfaceOrientationMask.all
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return self.orientationLock
}
В какой-то другой глобальной структуре или вспомогательном классе я создал AppUtility:
struct AppUtility {
static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
if let delegate = UIApplication.shared.delegate as? AppDelegate {
delegate.orientationLock = orientation
}
}
static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
self.lockOrientation(orientation)
UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
}
Затем в желаемом ViewController вы хотите заблокировать ориентацию:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
AppUtility.lockOrientation(.portrait)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
AppUtility.lockOrientation(.all)
}
Если iPad или универсальное приложение
Убедитесь, что "Требуется полноэкранный режим" отмечен в Target Settings -> General -> Deployment Info. supportedInterfaceOrientationsFor
делегат не будет вызван, если он не отмечен.