it-swarm.com.ru

Поворот полноэкранного режима AVPlayerViewController в портретном приложении

При встраивании AVPlayerViewController в приложение iOS только для портрета кажется, что приложение может застрять в странном макете, когда проигрыватель выходит из полноэкранного режима, если видео полноэкранно, пока устройство удерживается в горизонтальной ориентации.

Это ошибка или я что-то делаю неправильно?

Вот, как воспроизвести с чистым проектом, используя Xcode 9.4.1, Swift 4, iOS 11.4, симулятор или физическое устройство.

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")!)
}

Как это работает нормально:

  • Воспроизвести видео, нажмите на полный экран
  • Поворот в пейзаж, видео вращается
  • Закройте полный экран, приложение вернется в портрет независимо от ориентации экрана или устройства
  • например: https://imgur.com/a/MPFmzyH

Как это ломается:

  • Воспроизвести видео, повернуть устройство в альбомную ориентацию (экран не вращается)
  • Хит на весь экран
  • Выход из полноэкранного режима
  • Экран ломается, вращение не исправляет
  • например: https://imgur.com/a/hDdmu20
3
toemat

Когда вы покидаете плеер в полноэкранном режиме, вы входите в viewWillAppear вашего View Controller. Поэтому в viewWillAppear попробуйте установить рамку окна равной границам экрана.

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

Вы можете определить, когда проигрыватель станет полноэкранным, и выставить портрет или пейзаж для своего контроллера просмотра.

Это не лучшее решение, но, по крайней мере, позволяет избежать неправильного интерфейса:

    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