配置iOS?16?屏幕旋轉(zhuǎn)適配實(shí)例詳解
正文
我們公司的 app 只支持豎屏, 只有在視頻播放的時(shí)候才可以橫屏
, 所以這就需要我們強(qiáng)制去旋轉(zhuǎn)屏幕. 我想一般的 app 大概都會(huì)有這種需求.
最近隨著 iOS16
的更新, 線上的 app 在 iOS16
系統(tǒng)上不管用了, 原因就是蘋果從 iOS16
開(kāi)始, 更改了屏幕旋轉(zhuǎn)的機(jī)制, 以后都要用 UIWindowScence
這個(gè) API 類. 所以我們的 App 就只能根據(jù)版本去做適配, 新的要支持, 老的也要兼容.
在這里, 我就直接上干貨, 只展示重要代碼, 就不寫 demo
, 沒(méi)什么技術(shù)含量, 做為一個(gè)日常記錄分享而已.
重點(diǎn)提示
Xcode 14.0
MacOS 12.5
手機(jī) iOS15.1
和 iOS16
一. AppDelegate 配置
定義一個(gè) bool 類型的變量
全局控制否是橫屏代理方法根據(jù)這個(gè)變量來(lái)返回是 豎屏
還是 橫屏
, iOS16
及以上可以做到根據(jù)屏幕方向適配橫屏, 我們公司要求不高, 所以我們是強(qiáng)制右橫屏, 這一點(diǎn)是不太友好, 這不是重點(diǎn).
- 這一步
Swift
和ObjC
沒(méi)什么區(qū)別, 只是語(yǔ)法不同, 所以就只提供了Swift
代碼.
@main class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? // 定義一個(gè) bool 類型的變量 var isFullScreen: Bool = false func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { if isFullScreen { if #available(iOS 16.0, *) { // 16 及以上可以做到根據(jù)屏幕方向適配橫屏 return .landscape } else { // 16 以下不方便做, 所以我們是強(qiáng)制 右橫屏 return .landscapeRight } } return .portrait } }
二. 適配 iOS16 旋轉(zhuǎn)屏幕
在原來(lái)基礎(chǔ)上添加適配 iOS16
的代碼 在 VC
中點(diǎn)擊橫屏按鈕時(shí)進(jìn)行強(qiáng)制屏幕旋轉(zhuǎn), 這里強(qiáng)調(diào)一下, 播放器的橫屏按鈕操作最好是回調(diào)到當(dāng)前 VC 中去操作, setNeedsUpdateOfSupportedInterfaceOrientations()
這個(gè)方法是 VC 的對(duì)象方法, 這里同樣Swift
和 ObjC
沒(méi)什么區(qū)別, 只是語(yǔ)法不同.
func switchOrientation(isFullScreen: Bool) { let kAppdelegate = UIApplication.shared.delegate as? AppDelegate kAppdelegate?.isFullScreen = isFullScreen // 設(shè)置屏幕為橫屏 if #available(iOS 16.0, *) { setNeedsUpdateOfSupportedInterfaceOrientations() guard let scence = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return } let orientation: UIInterfaceOrientationMask = isFullScreen ? .landscape : .portrait let geometryPreferencesIOS = UIWindowScene.GeometryPreferences.iOS(interfaceOrientations: orientation) scence.requestGeometryUpdate(geometryPreferencesIOS) { error in print("強(qiáng)制\(isFullScreen ? "橫屏" : "豎屏" )錯(cuò)誤: \(error)") } } else { let oriention: UIDeviceOrientation = isFullScreen ? .landscapeRight : .portrait UIDevice.current.setValue(oriention.rawValue, forKey: "orientation") UIViewController.attemptRotationToDeviceOrientation() } // 更新 橫豎屏對(duì)應(yīng)的 UI // ... }
三. 強(qiáng)制旋轉(zhuǎn)屏幕
在播放器橫豎屏切換按鈕的回調(diào)方法中調(diào)用 旋轉(zhuǎn)屏幕方法即可, 不管手機(jī)有沒(méi)有打開(kāi)自動(dòng)旋轉(zhuǎn), 都可以實(shí)現(xiàn)屏幕方向切換.
// 播放器 - 全屏按鈕切換回調(diào) func playerViewRotateScreen(isFull: Bool) { switchOrientation(isFullScreen: isFull) }
四. 自動(dòng)旋轉(zhuǎn)
手機(jī)需要打開(kāi)自動(dòng)旋轉(zhuǎn)開(kāi)關(guān), 注冊(cè)屏幕旋轉(zhuǎn)通知, 監(jiān)聽(tīng)屏幕旋轉(zhuǎn)時(shí)的方向. 方法不只一種, 但是我就用下面這個(gè).
- 一定要注意下面這兩個(gè)方法, 否則有可能通知不生效, 一個(gè)開(kāi)啟一個(gè)關(guān)閉.
- UIDevice.current.beginGeneratingDeviceOrientationNotifications()
- UIDevice.current.endGeneratingDeviceOrientationNotifications()
注意:
我這里做的是 16 以下只支持右橫屏
, 16 不需要獲取設(shè)備方向, 因此可以支持左/右
橫屏. 這也是AppDelegate
中區(qū)分版本的原因.
友情提示 :
最好是把側(cè)滑返回手勢(shì)
給禁掉. 否則橫屏側(cè)滑返回就出問(wèn)題了, 當(dāng)然也可以做的更精細(xì)些, 橫屏?xí)r禁止. 我做驗(yàn)證就簡(jiǎn)單些.
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) UIDevice.current.beginGeneratingDeviceOrientationNotifications() NotificationCenter.default.addObserver(self, selector: #selector(screenChangedOrientation(_:)), name: UIDevice.orientationDidChangeNotification, object: nil) navigationController?.interactivePopGestureRecognizer?.isEnabled = false } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) navigationController?.interactivePopGestureRecognizer?.isEnabled = true } override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) NotificationCenter.default.removeObserver(self) UIDevice.current.endGeneratingDeviceOrientationNotifications() } // 橫豎屏監(jiān)聽(tīng) @objc private func screenChangedOrientation(_ notification: Notification) { let info = notification.userInfo guard let animated = info?["UIDeviceOrientationRotateAnimatedUserInfoKey"] as? Int, animated == 1 else { return } let orientation = UIDevice.current.orientation if orientation == UIDeviceOrientation.landscapeLeft || orientation == UIDeviceOrientation.landscapeRight { // 橫屏 videoView.changeScreenOrientation(isFull: true) } else if orientation == UIDeviceOrientation.portrait { // 豎屏 videoView.changeScreenOrientation(isFull: false) } }
以上就是配置iOS 16 屏幕旋轉(zhuǎn)適配實(shí)例詳解的詳細(xì)內(nèi)容,更多關(guān)于iOS 16 屏幕旋轉(zhuǎn)適配的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
IOS開(kāi)發(fā)仿微信右側(cè)彈出視圖實(shí)現(xiàn)
這篇文章主要介紹了IOS開(kāi)發(fā)仿微信右側(cè)彈出視圖實(shí)現(xiàn)的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家實(shí)現(xiàn)這樣類似的功能,需要的朋友可以參考下2017-10-10iOS實(shí)現(xiàn)抖音點(diǎn)贊動(dòng)畫效果
這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)抖音點(diǎn)贊動(dòng)畫效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-01-01