網站首頁 編程語言 正文
正文
我們公司的 app 只支持豎屏, 只有在視頻播放的時候才可以橫屏
, 所以這就需要我們強制去旋轉屏幕. 我想一般的 app 大概都會有這種需求.
最近隨著 iOS16
的更新, 線上的 app 在 iOS16
系統上不管用了, 原因就是蘋果從 iOS16
開始, 更改了屏幕旋轉的機制, 以后都要用 UIWindowScence
這個 API 類. 所以我們的 App 就只能根據版本去做適配, 新的要支持, 老的也要兼容.
在這里, 我就直接上干貨, 只展示重要代碼, 就不寫 demo
, 沒什么技術含量, 做為一個日常記錄分享而已.
重點提示
Xcode 14.0
MacOS 12.5
手機 iOS15.1
和 iOS16
一. AppDelegate 配置
定義一個 bool 類型的變量
全局控制否是橫屏代理方法根據這個變量來返回是 豎屏
還是 橫屏
, iOS16
及以上可以做到根據屏幕方向適配橫屏, 我們公司要求不高, 所以我們是強制右橫屏, 這一點是不太友好, 這不是重點.
- 這一步
Swift
和ObjC
沒什么區別, 只是語法不同, 所以就只提供了Swift
代碼.
@main class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? // 定義一個 bool 類型的變量 var isFullScreen: Bool = false func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { if isFullScreen { if #available(iOS 16.0, *) { // 16 及以上可以做到根據屏幕方向適配橫屏 return .landscape } else { // 16 以下不方便做, 所以我們是強制 右橫屏 return .landscapeRight } } return .portrait } }
二. 適配 iOS16 旋轉屏幕
在原來基礎上添加適配 iOS16
的代碼 在 VC
中點擊橫屏按鈕時進行強制屏幕旋轉, 這里強調一下, 播放器的橫屏按鈕操作最好是回調到當前 VC 中去操作, setNeedsUpdateOfSupportedInterfaceOrientations()
這個方法是 VC 的對象方法, 這里同樣Swift
和 ObjC
沒什么區別, 只是語法不同.
func switchOrientation(isFullScreen: Bool) { let kAppdelegate = UIApplication.shared.delegate as? AppDelegate kAppdelegate?.isFullScreen = isFullScreen // 設置屏幕為橫屏 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("強制\(isFullScreen ? "橫屏" : "豎屏" )錯誤: \(error)") } } else { let oriention: UIDeviceOrientation = isFullScreen ? .landscapeRight : .portrait UIDevice.current.setValue(oriention.rawValue, forKey: "orientation") UIViewController.attemptRotationToDeviceOrientation() } // 更新 橫豎屏對應的 UI // ... }
三. 強制旋轉屏幕
在播放器橫豎屏切換按鈕的回調方法中調用 旋轉屏幕方法即可, 不管手機有沒有打開自動旋轉, 都可以實現屏幕方向切換.
// 播放器 - 全屏按鈕切換回調 func playerViewRotateScreen(isFull: Bool) { switchOrientation(isFullScreen: isFull) }
四. 自動旋轉
手機需要打開自動旋轉開關, 注冊屏幕旋轉通知, 監聽屏幕旋轉時的方向. 方法不只一種, 但是我就用下面這個.
- 一定要注意下面這兩個方法, 否則有可能通知不生效, 一個開啟一個關閉.
- UIDevice.current.beginGeneratingDeviceOrientationNotifications()
- UIDevice.current.endGeneratingDeviceOrientationNotifications()
-
注意:
我這里做的是 16 以下只支持右橫屏
, 16 不需要獲取設備方向, 因此可以支持左/右
橫屏. 這也是AppDelegate
中區分版本的原因.
友情提示 :
最好是把側滑返回手勢
給禁掉. 否則橫屏側滑返回就出問題了, 當然也可以做的更精細些, 橫屏時禁止. 我做驗證就簡單些.
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() } // 橫豎屏監聽 @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) } }
原文鏈接:https://juejin.cn/post/7146134397375217695
相關推薦
- 2022-11-26 使用HttpClient消費ASP.NET?Web?API服務案例_實用技巧
- 2023-02-07 C#利用異或算法實現加密解密_C#教程
- 2022-09-25 注解@Autowired如何自動裝配
- 2022-08-13 Redis中String字符串sdshdr結構體的講解
- 2022-03-14 Failed to load ApplicationContext異常的解決思路
- 2023-03-29 Python利用pynimate實現制作動態排序圖_python
- 2022-11-03 C++命名空間使用詳細介紹_C 語言
- 2022-06-20 React函數組件與類組件使用及優劣對比_React
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支