⚠️设备方向 != 界面方向⚠️
Swift 5.* iOS16 及以下版本
你应该明确区分:
- 设备方向 => 表示物理设备的方向
- 界面方向 => 表示屏幕上显示的界面方向
有许多情况下这两个值不匹配,比如:
在大多数情况下,你会想要使用界面方向,你可以通过 window 获取它:
private var windowInterfaceOrientation: UIInterfaceOrientation? {
return UIApplication.shared.windows.first?.windowScene?.interfaceOrientation
}
如果您也想支持 < iOS 13(例如iOS 12),则应执行以下操作:
private var windowInterfaceOrientation: UIInterfaceOrientation? {
if #available(iOS 13.0, *) {
return UIApplication.shared.windows.first?.windowScene?.interfaceOrientation
} else {
return UIApplication.shared.statusBarOrientation
}
}
现在你需要定义在哪里对窗口界面方向的更改做出反应。有多种方法可以实现,但最佳解决方案是在willTransition(to newCollection: UITraitCollection
中执行。
这个继承的UIViewController方法可以被覆盖,每次接口方向更改时都会触发它。因此,您可以在后者中进行所有修改。
以下是一个解决方案示例:
class ViewController: UIViewController {
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
super.willTransition(to: newCollection, with: coordinator)
coordinator.animate(alongsideTransition: { (context) in
guard let windowInterfaceOrientation = self.windowInterfaceOrientation else { return }
if windowInterfaceOrientation.isLandscape {
} else {
}
})
}
private var windowInterfaceOrientation: UIInterfaceOrientation? {
return UIApplication.shared.windows.first?.windowScene?.interfaceOrientation
}
}
通过实现这种方法,您将能够对接口的任何方向变化做出反应。但请记住,在打开应用程序时不会触发它,因此您还需要在 viewWillAppear()
中手动更新您的界面。
我创建了一个示例项目,突显设备方向和界面方向之间的区别。此外,它将帮助您了解根据您决定何时更新UI的生命周期步骤而产生的不同行为。
随意克隆并运行以下存储库:
https://github.com/wjosset/ReactToOrientation