禁止自動橫屏下的視頻播放強制旋轉

問題的由來

這個標題有點繞,因此我來解釋一下。git

以前項目開發的時候須要用到一個視頻播放的第三方庫,可是這個第三方庫在從小屏幕播放切換到大屏幕播放的時候,是須要開啓項目的自動旋轉支持的。也就是 github

圖一

第三方視頻播放庫 BMPlayer 這個庫中有許多細節的部分沒法知足實際使用,所以我下了源碼後本身根據需求修改。swift

然而實際應用中,許多的 App 的要求是須要禁止橫屏的。由於大多數 App(竊覺得除了遊戲之外的)即便寫好了約束,也都不會針對橫屏下的 UI 做對應的優化。 所以咱們須要本身針對工程禁用橫屏狀況下,播放視頻時切換到全屏作本身的優化app

問題的擴展

以前搜索播放框架的時候沒有找到適當的,所以最後決定本身把 BMPlayer的源碼 down下來本身修改。雖然最後解決了(這也是本篇文章下面主要闡述的內容),可是解決方案是在AppDelegate中增長一個變量來控制當前App 的方向。實際上仍是增長了庫和工程之間的耦合度。暫時還未找到更好的解決方案。框架

實現的效果

效果圖.gif

代碼和說明(Swift 爲例)

下面的源碼中略去了沒必要要的代碼函數

AppDelegate.swift 中

let appDelegate = UIApplication.shared.delegate as! AppDelegate
class AppDelegate: UIResponder, UIApplicationDelegate, WXApiDelegate {
    var deviceOrientation = UIInterfaceOrientationMask.portrait
    
    // 去實現這個回調代理
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return deviceOrientation
    }
}
複製代碼

在視頻播放庫中控制它的方向

點擊全屏播放和恢復小屏幕時候兩個按鈕的對應方法測試

private func forceToPlayOnFullScreen() {
    let currentOrientation = UIDevice.current.orientation
    print("向右旋轉前 當前的方向 = ", currentOrientation.rawValue)
    
    appDelegate.deviceOrientation = .landscapeRight
    // 若是防止用戶在進入當前頁面時手機橫置,那麼當前的 device orientation 是 landscapeRight
    // 這時候,咱們再去設置 landscapeRight,是不會引發廣播 "UIDeviceOrientationDidChangeNotification",所以手動調用一次
    let portraitValue = UIInterfaceOrientation.portrait.rawValue
    UIDevice.current.setValue(portraitValue, forKey: "orientation")
    
    let rightValue = UIInterfaceOrientation.landscapeRight.rawValue
    UIDevice.current.setValue(rightValue, forKey: "orientation")
    
}

private func forceToPlayOnOriginScreen() {
    let currentOrientation = UIDevice.current.orientation
    print("恢復垂直前當前的方向 = ", currentOrientation.rawValue)
    
    // 這裏爲何要寫兩遍,在下面說明
    appDelegate.deviceOrientation = .portrait
    let rightValue = UIInterfaceOrientation.landscapeRight.rawValue
    UIDevice.current.setValue(rightValue, forKey: "orientation")
    
    let portraitValue = UIInterfaceOrientation.portrait.rawValue
    UIDevice.current.setValue(portraitValue, forKey: "orientation")
    
}

複製代碼

關於代碼設置了兩次方向的說明

必定很奇怪,爲何兩次代碼的調用中,設置方向的代碼要寫兩遍呢優化

UIDevice.current.setValueui

這是由於,視頻播放庫,這裏須要去獲取一個系統的廣播 UIDeviceOrientationDidChangeNotification.spa

說明

假設咱們當前的屏幕是橫屏的狀況

以 Bilibili 的播放頁面爲例

此時系統會利用陀螺儀,雖然咱們視覺上看上去,他並無向右旋轉,可是當前的方向UIDevice.current.orientation會變成landScapeRight.

所以咱們若是這時候去調用

let rightValue = UIInterfaceOrientation.landscapeRight.rawValue
UIDevice.current.setValue(rightValue, forKey: "orientation")
複製代碼

這個函數的時候,不會觸發廣播,由於系統會認爲,其實個人方向沒有變化啊!

這也就是爲何上面咱們會先讓他的方向設爲默認的 portrait再切回landscapeRight. 我曾經誤覺得界面會不會旋轉回去一次再賺回來,可是實際測試發現卻是沒有出現相似的情景。

相關文章
相關標籤/搜索