日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

配置iOS?16?屏幕旋轉適配實例詳解_IOS

作者:Andy_GF ? 更新時間: 2022-11-14 編程語言

正文

我們公司的 app 只支持豎屏, 只有在視頻播放的時候才可以橫屏, 所以這就需要我們強制去旋轉屏幕. 我想一般的 app 大概都會有這種需求.

最近隨著 iOS16 的更新, 線上的 app 在 iOS16 系統上不管用了, 原因就是蘋果從 iOS16 開始, 更改了屏幕旋轉的機制, 以后都要用 UIWindowScence 這個 API 類. 所以我們的 App 就只能根據版本去做適配, 新的要支持, 老的也要兼容.

在這里, 我就直接上干貨, 只展示重要代碼, 就不寫 demo, 沒什么技術含量, 做為一個日常記錄分享而已.

重點提示

Xcode 14.0MacOS 12.5手機 iOS15.1iOS16

一. AppDelegate 配置

定義一個 bool 類型的變量

全局控制否是橫屏代理方法根據這個變量來返回是 豎屏 還是 橫屏, iOS16 及以上可以做到根據屏幕方向適配橫屏, 我們公司要求不高, 所以我們是強制右橫屏, 這一點是不太友好, 這不是重點.

  • 這一步 SwiftObjC 沒什么區別, 只是語法不同, 所以就只提供了 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 的對象方法, 這里同樣SwiftObjC 沒什么區別, 只是語法不同.

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

欄目分類
最近更新