present 场景
关注点
present 页面时,重点是这两个属性:
swift
override var supportedInterfaceOrientations: UIInterfaceOrientationMask
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation
supportedInterfaceOrientations:页面允许方向preferredInterfaceOrientationForPresentation:模态展示时首选方向
必须满足的规则
preferredInterfaceOrientationForPresentation 必须包含在 supportedInterfaceOrientations 中。
错误示例:
swift
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
.landscape
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
.portrait
}
iOS 16 及以下会崩溃:
preferredInterfaceOrientationForPresentation 'portrait' must match a supported interface orientation: 'landscapeLeft, landscapeRight'!
iOS 17 为警告,不崩溃,但仍属于非法配置。
与应用级方向的关系
present 页面还必须与应用级可用方向有交集。
若应用只允许竖屏,而被 present 页面只支持横屏,会出现:
Supported orientations has no common orientation with the application...
推荐写法
swift
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
.landscape
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
.landscapeRight
}
如果需要在多个页面混用横竖屏,可在 AppDelegate 放开应用级方向:
swift
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
.all
}
push 场景
关注点
push 页面只用看:
swift
override var supportedInterfaceOrientations: UIInterfaceOrientationMask
preferredInterfaceOrientationForPresentation 不是 push 的控制项。
与应用级方向的关系
如果应用级只允许竖屏,即使页面声明横屏,也不会崩溃,但横屏不会生效。
iOS 版本行为
iOS 15 及以下
从竖屏页 push 到横屏页,不会自动旋转,需要手动触发:
swift
let value: UIInterfaceOrientation = orientation.contains(.landscapeRight) ? .landscapeRight : .portrait
UIDevice.current.setValue(value.rawValue, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation()
iOS 16 及以上
会自动旋转。
如需显式请求方向更新,可用 iOS 16 新接口:
swift
guard let windowScene = self.view.window?.windowScene else {
return
}
let preferences = UIWindowScene.GeometryPreferences.iOS(interfaceOrientations: orientation)
windowScene.requestGeometryUpdate(preferences) { _ in }
self.setNeedsUpdateOfSupportedInterfaceOrientations()