一. 需求
APP中需要支持橫屏和豎屏,并在不同的頁(yè)面 可支持的屏幕旋轉(zhuǎn)方向不一致
- 整體豎屏,部分強(qiáng)制橫屏
-
整體橫屏,部分強(qiáng)制豎屏
如下:
橫屏.gif
二. 實(shí)現(xiàn)
不廢話,直接上代碼
1. 代碼層
1)AppDelegate.swift文件添加對(duì)屏幕旋轉(zhuǎn)的支持
添加屬性:
var blockRotation: UIInterfaceOrientationMask = .portrait{
didSet{
if blockRotation.contains(.portrait){
//強(qiáng)制設(shè)置成豎屏
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
}else{
//強(qiáng)制設(shè)置成橫屏
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
}
}
}
添加 屏幕支持的旋轉(zhuǎn)方向:
extension AppDelegate{
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return blockRotation
}
}
2)在屏幕需要更改旋轉(zhuǎn)狀態(tài)的位置更新旋轉(zhuǎn)方向
為方便獲取AppDelegate中的blockRotation屬性,添加常量
let kAppdelegate: AppDelegate? = UIApplication.shared.delegate as? AppDelegate
不同的旋轉(zhuǎn)情況,配置如下:
a. 豎屏First -> 橫屏Second
在push跳轉(zhuǎn)前更改旋轉(zhuǎn)方向
@objc func onClickJumpToNextPageBtnAction(){
//進(jìn)入下一頁(yè)面,轉(zhuǎn)換為橫屏
let rotation : UIInterfaceOrientationMask = [.landscapeLeft, .landscapeRight]
kAppdelegate?.blockRotation = rotation
let secondVC = SecondVC()
navigationController?.pushViewController(secondVC, animated: true)
}
b. 橫屏Second -> 豎屏First
在pop返回前更改旋轉(zhuǎn)方向
@objc func onClickBackBtnAction(){
//設(shè)置豎屏
kAppdelegate?.blockRotation = .portrait
navigationController?.popViewController(animated: true)
}
c. 橫屏First -> 橫屏Third
屏幕旋轉(zhuǎn)方向未發(fā)生變化,不需要做任何處理
3)做優(yōu)化完善針對(duì)特殊的現(xiàn)象
實(shí)現(xiàn)以上代碼基本可以實(shí)現(xiàn)部分頁(yè)面豎屏,部分頁(yè)面強(qiáng)制橫屏,但是還會(huì)有一些屏幕旋轉(zhuǎn)的瑕疵,可通過(guò)如下方式完善
a. 豎屏First -> 橫屏Second -> 橫屏Third
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
//設(shè)置原因: 手機(jī)豎屏進(jìn)入橫屏,狀態(tài)欄默認(rèn)隱藏;iPad顯示異常
UIApplication.shared.setStatusBarHidden(false, with: .none)
}
需要在SecondVC中添加上述代碼,設(shè)置狀態(tài)條不隱藏,否則iPhone上狀態(tài)欄會(huì)默認(rèn)隱藏(iPad不隱藏,顯示正常)。異常情況顯示如下:

***b. 豎屏First -> 橫屏Second ***
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//如果不設(shè)置該頁(yè)面的豎屏, 在屏幕鎖定打開(kāi)的情況下,豎屏First -> 橫屏Second -> 切換到后臺(tái) -> 進(jìn)入前臺(tái) -> 返回豎屏First 會(huì)出現(xiàn)狀態(tài)欄已豎屏,其他內(nèi)容仍然橫屏切換的問(wèn)題
UIViewController.attemptRotationToDeviceOrientation()
}
需要在FirstVC中添加上述代碼,否則在屏幕鎖定打開(kāi)的情況下,豎屏First -> 橫屏Second -> 切換到后臺(tái) -> 進(jìn)入前臺(tái) -> 返回豎屏First 會(huì)出現(xiàn)狀態(tài)欄已豎屏,其他內(nèi)容仍然橫屏切換的問(wèn)題。異常情況顯示如下:

正常展示如下:

2.文件配置
1)設(shè)置屏幕支持的旋轉(zhuǎn)方向

2)設(shè)置
View controller-based status bar appearance為NO

3. demo地址:
https://github.com/merrylaugh/ScreenOrientationDemo
三. 細(xì)節(jié)解析
1.配置文件 View controller-based status bar appearance含義:
View controller-based status bar appearance可以設(shè)置YES或NO
1)YES: View Controller的對(duì)statusBar的設(shè)置優(yōu)先級(jí)高于AppDelegate
2)NO: application的設(shè)置優(yōu)先級(jí)最高
參考: http://blog.csdn.net/yongyinmg/article/details/39928367
以上僅是個(gè)人使用總結(jié),歡迎批評(píng)指正補(bǔ)充~~~~~~~
