1 NavigationController與AutoRotate
1.1 如果一個(gè)controller屬于UINavigationController,controller的shouldAutorotate方法會(huì)失效
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在特定情況下不能旋屏,其他時(shí)候可以。如present出半屏的視圖時(shí),不可旋屏
override var shouldAutorotate: Bool {
return !lockRotation //通過設(shè)置lockRotation
}
1.5 present 和 shouldAutorotate
如果present的modal不是fullScreen,那么present出來的vc的shouldAutorotate是不起作用的
1.6 強(qiáng)制旋屏
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let value = UIInterfaceOrientation.landscapeLeft.rawValue // 有動(dòng)效
// let value = UIDeviceOrientation.landscapeLeft.rawValue // 無動(dòng)效
UIDevice.current.setValue(value, forKey: "orientation")
}
2 生命周期方法 與 Orientation
這個(gè)方法中,出方法之前,Device的方向是新的,StatusBar的方向是舊的。
/**
* 注意: 在iOS15中, override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)中
* UIInterfaceOrientation是滯后的, 也就是旋屏前的方向
* UIDevice.current.orientation是旋屏后的最終方向, 并且與設(shè)備的實(shí)際方向無關(guān), 而是statusBar的方向(如手機(jī)橫置時(shí), 點(diǎn)bilibli的非全屏播放, 這時(shí)手機(jī)是橫向, 頁面內(nèi)容則是豎著的, 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已經(jīng)廢棄了,Device orientation包含了FaceUp等
if orientation.isLandscape {
//橫屏布局
} else {
//豎屏布局
}
}