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

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

配置iOS?16?屏幕旋轉(zhuǎn)適配實(shí)例詳解_IOS

作者:Andy_GF ? 更新時(shí)間: 2022-11-14 編程語(yǔ)言

正文

我們公司的 app 只支持豎屏, 只有在視頻播放的時(shí)候才可以橫屏, 所以這就需要我們強(qiáng)制去旋轉(zhuǎn)屏幕. 我想一般的 app 大概都會(huì)有這種需求.

最近隨著 iOS16 的更新, 線上的 app 在 iOS16 系統(tǒng)上不管用了, 原因就是蘋(píng)果從 iOS16 開(kāi)始, 更改了屏幕旋轉(zhuǎn)的機(jī)制, 以后都要用 UIWindowScence 這個(gè) API 類(lèi). 所以我們的 App 就只能根據(jù)版本去做適配, 新的要支持, 老的也要兼容.

在這里, 我就直接上干貨, 只展示重要代碼, 就不寫(xiě) demo, 沒(méi)什么技術(shù)含量, 做為一個(gè)日常記錄分享而已.

重點(diǎn)提示

Xcode 14.0MacOS 12.5手機(jī) iOS15.1iOS16

一. AppDelegate 配置

定義一個(gè) bool 類(lèi)型的變量

全局控制否是橫屏代理方法根據(jù)這個(gè)變量來(lái)返回是 豎屏 還是 橫屏, iOS16 及以上可以做到根據(jù)屏幕方向適配橫屏, 我們公司要求不高, 所以我們是強(qiáng)制右橫屏, 這一點(diǎn)是不太友好, 這不是重點(diǎn).

  • 這一步 SwiftObjC 沒(méi)什么區(qū)別, 只是語(yǔ)法不同, 所以就只提供了 Swift 代碼.
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    // 定義一個(gè) bool 類(lèi)型的變量
    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ì)象方法, 這里同樣SwiftObjC 沒(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)
        }
    }

原文鏈接:https://juejin.cn/post/7146134397375217695

欄目分類(lèi)
最近更新