在AVPlayerViewController中完成按钮单击事件

我想在AVPlayerViewController中播放本地video,但没有找到完成按钮的点击事件。

我的video能够在AVPlayerViewController中播放,但我没有找到下一个按钮,上一个按钮和完成按钮点击事件。

正式没有Done Button点击事件,Apple的工程师在这里说了这件事。

至于我的研究,我发现如果单击Done Button,有一种但实际上是间接的方式来获取事件。

我发现AVPlayerViewController的唯一变量是AVPlayerViewController.view.frame,它是在点击完成按钮时更改的。 首先,view.frame出现在viewController的中心。

如果你用animated : true呈现它animated : true它会转到viewController的底部并返回到中心。 单击完成后,它会返回到底部。

如果您使用animated : false显示它animated : false将只有2个更改:当您开始播放video时,框架将位于viewController的中心,而当单击完成时,框架将位于底部。

因此,如果您在回调中向AVPlayerViewController.view.frame添加观察者present(PlayerViewController, animated : true)您将只获得一次观察者调用,当单击完成按钮并且video视图将不在屏幕上时。

在我的例子中,AVPlayerViewController以模态方式呈现动画。 以下代码对我有用:

Swift 3.0

 override func viewDidLoad() { super.viewDidLoad() let videoURL = NSURL(fileURLWithPath:Bundle.main.path(forResource: "MyVideo", ofType:"mp4")!) let player = AVPlayer(url: videoURL as URL) present(playerViewController, animated: false) { () -> Void in player.play() self.playerViewController.player = player self.playerViewController.addObserver(self, forKeyPath: #keyPath(UIViewController.view.frame), options: [.old, .new], context: nil) }} override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { print(self.playerViewController.view.frame) //Player view is out of the screen and //You can do your custom actions } 

另外,我发现当你单击Done时,AVPlayerViewController没有被解雇,你可以在ParentViewController.presentedViewController看到它,所以你不能将观察者添加到这个属性

我这样做是为了从AVPlayerViewController获取Done按钮单击事件。

首先,像bellow一样创建Notification.Name的扩展名

 extension Notification.Name { static let kAVPlayerViewControllerDismissingNotification = Notification.Name.init("dismissing") } 

现在,创建AVPlayerViewController的扩展并覆盖viewWillDisappear ,如下所示

 // create an extension of AVPlayerViewController extension AVPlayerViewController { // override 'viewWillDisappear' open override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // now, check that this ViewController is dismissing if self.isBeingDismissed == false { return } // and then , post a simple notification and observe & handle it, where & when you need to..... NotificationCenter.default.post(name: .kAVPlayerViewControllerDismissingNotification, object: nil) } } 

这仅仅是处理按钮事件的基本function。

快乐的编码……

我遇到了同样的问题,我找到了另一个技巧(与YoutubePlayer swift框架一起工作,它在webview中播放video,但你可能能够适应其他用途)。

在我的情况下,按Done按钮并按全屏video播放器上的Pause按钮都会导致YoutubePlayer上出现pause事件。 但是,当video在不同的窗口中播放时,我将应用程序的主窗口子类化,并覆盖了becomeKeyresignKey函数来存储我的窗口是否是关键窗口,如下所示:

 class MyWindow:UIWindow { override func becomeKey() { Services.appData.myWindowIsKey = true } override func resignKey() { Services.appData.myWindowIsKey = false } } 

有了这个,我可以在video状态暂停时检查我的窗口是否是键 – 当按下Done按钮时,我的窗口关键窗口,我可以关闭我的video视图控制器,并在Pause情况下我的窗口不是关键窗口,所以我什么都不做。

这是@vmchar的答案的一个小改进:

我们可以使用.isBeingDismissed方法来确保关闭AVPlayerViewController而不是分析帧。

 ... let videoURL = NSURL(fileURLWithPath:"video.mp4") let player = AVPlayer(url: videoURL as URL) present(playerViewController!, animated: false) { () -> Void in player.play() self.playerViewController!.player = player self.playerViewController!.addObserver(self, forKeyPath:#keyPath(UIViewController.view.frame), options: [.old, .new], context: nil) ... 

然后观察价值

 override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if (playerViewController!.isBeingDismissed) { // Video was dismissed -> apply logic here } } 

您可以查看此Stackoverflowpost ,这是一个github的项目供参考。 你将不得不使用这个:

  self.showsPlaybackControls = true 

另请查看Apple的文档