Origin of the problem

This title is a little convoluted, so LET me explain.

The previous project development needs to use a third-party library for video playback, but when the third-party library switches from small screen to large screen, it needs to enable the automatic rotation support of the project. That is

The third-party video player library BMPlayer has many details that can not meet the actual use, so I put the source code under their own needs to modify.

However, in practical applications, the requirements of many apps are to prohibit landscape screen. Because most apps (except for games) don’t optimize the UI for landscape, even if the constraints are written. Therefore, we need to do our own optimization for the project to disable landscape screen and switch to full screen when playing video

Extension of the problem

I did not find the appropriate frame when I searched for it, so I decided to take down the source code of BMPlayer and modify it myself. The solution is to add a variable to the AppDelegate to control the direction of the current App. It actually increases the degree of coupling between the library and the project. A better solution has not yet been found.

Achieved effect

Codes and Instructions (SwiftAs an example)

Unnecessary code has been omitted from the source code below

In the AppDelegate. Swift

let appDelegate = UIApplication.shared.delegate as! AppDelegate
class AppDelegate: UIResponder.UIApplicationDelegate.WXApiDelegate {
    var deviceOrientation = UIInterfaceOrientationMask.portrait
    
    // Implement the callback proxy
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return deviceOrientation
    }
}
Copy the code

Control its direction in the video player library

Click the corresponding method of two buttons when full screen play and restore small screen

private func forceToPlayOnFullScreen(a) {
    let currentOrientation = UIDevice.current.orientation
    print("Current direction before turning right =", currentOrientation.rawValue)
    
    appDelegate.deviceOrientation = .landscapeRight
    // The current Device orientation is landscapeRight if the user's phone is not landscapeRight when entering the current page
    / / at this time, we'll set landscapeRight, won't cause radio "UIDeviceOrientationDidChangeNotification", so call a manual
    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(a) {
    let currentOrientation = UIDevice.current.orientation
    print("Current direction before returning to vertical =", currentOrientation.rawValue)
    
    // Why do I write this twice
    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")}Copy the code

Note that the code sets the direction twice

It must be strange to write the direction setting code twice in two calls to the code

UIDevice.current.setValue

This is because the video library, need to obtain a system of radio UIDeviceOrientationDidChangeNotification here.

instructions

Let’s say our current screen is landscape

The system will use a gyroscope, although we look on the vision, he didn’t spin to the right, but the direction of the current UIDevice. Current. The orientation will become landScapeRight.

So if we call it at this point

let rightValue = UIInterfaceOrientation.landscapeRight.rawValue
UIDevice.current.setValue(rightValue, forKey: "orientation")
Copy the code

This function will not trigger the broadcast, because the system will say, in fact, my direction has not changed ah!

This is why we use the portrait orientation as the default before returning the overall image. I was under the illusion that the interface would rotate back and earn back, but the actual testing didn’t show anything like that.