禁止自動橫屏下的視訊播放強制旋轉
阿新 • • 發佈:2018-11-22
問題的由來
這個標題有點繞,所以我來解釋一下。
之前專案開發的時候需要用到一個視訊播放的第三方庫,但是這個第三方庫在從小螢幕播放切換到大螢幕播放的時候,是需要開啟專案的自動旋轉支援的。也就是
第三方視訊播放庫 BMPlayer 這個庫中有許多細節的部分無法滿足實際使用,因此我下了原始碼後自己根據需求修改。
然而實際應用中,許多的 App 的要求是需要禁止橫屏的。因為大多數 App(竊以為除了遊戲以外的)即使寫好了約束,也都不會針對橫屏下的 UI 作對應的優化。 因此我們需要自己針對工程禁用橫屏情況下,播放視訊時切換到全屏做自己的優化
問題的擴充套件
之前搜尋播放框架的時候沒有找到適當的,因此最後決定自己把 BMPlayer
down
下來自己修改。雖然最後解決了(這也是本篇文章下面主要闡述的內容),但是解決方案是在AppDelegate
中增加一個變數來控制當前App
的方向。實際上還是增加了庫和工程之間的耦合度。暫時還未找到更好的解決方案。
實現的效果
程式碼和說明(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.setValue
這是因為,視訊播放庫,這裡需要去獲取一個系統的廣播 UIDeviceOrientationDidChangeNotification
.
說明
假設我們當前的螢幕是橫屏的情況
此時系統會利用陀螺儀,雖然我們視覺上看上去,他並沒有向右旋轉,但是當前的方向
UIDevice.current.orientation
會變成landScapeRight
.
因此我們如果這時候去呼叫
let rightValue = UIInterfaceOrientation.landscapeRight.rawValue UIDevice.current.setValue(rightValue, forKey: "orientation") 複製程式碼
這個函式的時候,不會觸發廣播,因為系統會認為,其實我的方向沒有變化啊!
這也就是為什麼上面我們會先讓他的方向設為預設的 portrait
再切回landscapeRight
. 我曾經誤以為介面會不會旋轉回去一次再賺回來,但是實際測試發現倒是沒有出現類似的情景。