如文档所述,
视图控制器可以覆盖supportedInterfaceOrientations方法来限制支持的方向列表。
因此,我们需要重写shouldAutorotate
和supportedInterfaceOrientation
以针对视图控制器
。
通常,系统仅在窗口的根视图控制器或呈现为填充整个屏幕的视图控制器上调用此方法。
如果您有非常简单的配置,例如您的目标视图控制器
是window
的rootViewController
或被呈现以覆盖整个屏幕,则会起作用。
但是当您拥有其他配置时,例如您的目标视图控制器
嵌入在某些其他容器视图控制器中,例如 UINavigationController
或 UITabBarController
,那么应用程序的窗口现在只会询问其 rootViewController
(现在是容器视图控制器
)的 supportedInterfaceOrientation
。
现在进一步阅读文档。
子视图控制器使用父视图控制器提供的窗口部分,并且不再直接参与有关支持哪些旋转方向的决策。
因此,这些容器视图控制器的默认实现可能不会询问其子级的supportedInterfaceOrientation
偏好设置。
所以,为了允许我们的目标子视图控制器
指定其supportedInterfaceOrientation
,我们需要告诉它们的容器视图控制器这样做。
在UINavigationController
的情况下:
extension UINavigationController {
open override var shouldAutorotate: Bool {
return true
}
open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return topViewController?.supportedInterfaceOrientations ?? .allButUpsideDown
}
}
而且在 UITabBarController
的情况下
extension UITabBarController {
open override var shouldAutorotate: Bool {
return true
}
open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return selectedViewController?.supportedInterfaceOrientations ?? .allButUpsideDown
}
}
编辑
为了在您的视图控制器中实现正确的旋转行为,您应该子类化这些ContainerViewController
(UINavigationController
, UITabBarController
, UISplitViewController
等),然后覆盖这些属性,因为全局扩展这些UIKit
类会导致意外的行为,如自定义现有类所述。
如果在分类中声明的方法名称与原始类中的方法名称相同,或者与同一类别上的另一个类别中的方法名称相同(甚至是超类),则在运行时使用哪个方法实现的行为是未定义的。如果您正在使用自己的类别与自己的类一起使用,则可能不太可能出现此问题,但在使用类别将方法添加到标准Cocoa或Cocoa Touch类中时可能会出现问题。