1 NavigationController与AutoRotate
1.1 如果一个controller属于UINavigationController,controller的shouldAutorotate方法会失效
1.2 希望UINavigationController中所有controller都不能旋屏
class LNNaviVCNoRotation: UINavigationController {
override var shouldAutorotate: Bool {
return false
}
}
1.3 希望UINavigationController中的controller自己决定能不能旋屏
class LNNaviController: UINavigationController {
override open var shouldAutorotate: Bool {
get {
if let visibleVC = visibleViewController {
return visibleVC.shouldAutorotate
}
return super.shouldAutorotate
}
}
override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
get {
if let visibleVC = visibleViewController {
return visibleVC.preferredInterfaceOrientationForPresentation
}
return super.preferredInterfaceOrientationForPresentation
}
}
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask{
get {
if let visibleVC = visibleViewController {
return visibleVC.supportedInterfaceOrientations
}
return super.supportedInterfaceOrientations
}
}
}
//特定controller中
override var shouldAutorotate: Bool {
return true
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
return .landscapeLeft
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscape
}
1.4 如果希望controller在特定情况下不能旋屏,其他时候可以。如present出半屏的视图时,不可旋屏
override var shouldAutorotate: Bool {
return !lockRotation //通过设置lockRotation
}
1.5 present 和 shouldAutorotate
如果present的modal不是fullScreen,那么present出来的vc的shouldAutorotate是不起作用的
1.6 强制旋屏
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let value = UIInterfaceOrientation.landscapeLeft.rawValue // 有动效
// let value = UIDeviceOrientation.landscapeLeft.rawValue // 无动效
UIDevice.current.setValue(value, forKey: "orientation")
}
2 生命周期方法 与 Orientation
这个方法中,出方法之前,Device的方向是新的,StatusBar的方向是旧的
。
/**
* 注意: 在iOS15中, override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)中
* UIInterfaceOrientation是滞后的, 也就是旋屏前的方向
* UIDevice.current.orientation是旋屏后的最终方向, 并且与设备的实际方向无关, 而是statusBar的方向(如手机横置时, 点bilibli的非全屏播放, 这时手机是横向, 页面内容则是竖着的, UIDevice.current.orientation为 portrait)
*/
//controller
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
guard !lockRotation else { return }
//
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let orientation = UIDevice.current.orientation //注意statusBarOrietation已经废弃了,Device orientation包含了FaceUp等
if orientation.isLandscape {
//横屏布局
} else {
//竖屏布局
}
}