webentwicklung-frage-antwort-db.com.de

AVPlayerViewController Vollbild-Rotationsverhalten nur im Hochformat

Wenn Sie einen AVPlayerViewController in eine iOS-App mit Hochformat einbetten, kann es passieren, dass die App in einem seltsamen Layout hängen bleibt, wenn der Player den Vollbildmodus verlässt, wenn das Video im Vollbildmodus angezeigt wird, während das Gerät im Querformat gehalten wird.

Ist das ein Fehler oder mache ich etwas falsch?

So reproduzieren Sie ein sauberes Projekt mit Xcode 9.4.1, Swift 4, iOS 11.4, einem Simulator oder einem physischen Gerät.

ViewController.Swift

override func viewDidLoad() {
    super.viewDidLoad()

    //Create the player and add as child view controller
    let playerVC = AVPlayerViewController()
    self.addChildViewController(playerVC)

    //Place player's view in self
    playerVC.view.frame = CGRect(x: 10, y: 40, width: 355, height: 200)
    self.view.addSubview(playerVC.view)

    //Load example video
    playerVC.player = AVPlayer(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")!)
}

Wie es normalerweise funktioniert:

  • Video abspielen, Vollbildmodus
  • In Landschaft drehen, Video dreht sich
  • Schließen Sie den Vollbildmodus. Die App kehrt unabhängig von der Ausrichtung des Bildschirms oder des Geräts zum Portrait zurück
  • ex: https://imgur.com/a/MPFmzyH

Wie es bricht:

  • Video abspielen, Gerät in Querformat drehen (Bildschirm dreht sich nicht)
  • Vollbild treffen
  • Vollbild verlassen
  • Bildschirm bricht, dreht sich nicht
  • ex: https://imgur.com/a/hDdmu20
3
toemat

Wenn Sie den Player im Vollbildmodus verlassen, gelangen Sie in viewWillAppear Ihres View Controllers. Versuchen Sie in viewWillAppear, Ihren Fensterrahmen so einzustellen, dass er Ihren Bildschirmgrenzen entspricht.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
    appDelegate.window?.rootViewController?.view.frame = UIScreen.main.bounds
}
4
Ivan Georgiev

Sie können feststellen, wann der Player Vollbild wird, und das Hoch- oder Querformat für den View-Controller erzwingen.

Dies ist nicht die beste Lösung, vermeidet aber zumindest die beschädigte Benutzeroberfläche:

    import AVFoundation
    import AVKit

    var isPlayerFullscreen: Bool = false

    override func viewDidLoad() {
        super.viewDidLoad()

        //Create the player and add as child view controller
        let playerVC = AVPlayerViewController()
        self.addChildViewController(playerVC)

        //Place player's view in self
        playerVC.view.frame = CGRect(x: 10, y: 40, width: 355, height: 200)
        self.view.addSubview(playerVC.view)

        //Load example video
        playerVC.player = AVPlayer(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")!)

        //Add an observer for playerVC object
        playerVC.addObserver(self, forKeyPath: "videoBounds", options: NSKeyValueObservingOptions.new, context: nil)
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
    {
        if keyPath == "videoBounds", let rect = change?[.newKey] as? NSValue
        {
            let playerRect: CGRect = rect.cgRectValue
            if playerRect.size.height <= 200 {
                print("Video not in full screen")                
                UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
isPlayerFullscreen = false
            } else {
                print("Video in full screen")
                isPlayerFullscreen = true
            }
        }
    }

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return isPlayerFullscreen ? UIInterfaceOrientationMask.landscape: UIInterfaceOrientationMask.portrait
    }

    override var shouldAutorotate: Bool {
        return true
    }
0
Nabil Safatli