[英]How to detect fullscreen mode using AVPlayerViewController in Swift?
I am trying to detect when the AVPlayerViewController
is in full-screen mode, but I'm having a difficult time achieving this.我试图检测
AVPlayerViewController
何时处于全屏模式,但我很难实现这一点。 I'd like to know when the user selects the expand button to enter full screen as shown here:我想知道用户何时选择展开按钮进入全屏,如下所示:
I've added the appropriate observer per these suggestions:我已经根据这些建议添加了适当的观察者:
The appropriate code:相应的代码:
var avWidth:CGFloat = 375
var avHeight:CGFloat = 300
override func viewDidLoad()
{
super.viewDidLoad()
let path = NSBundle.mainBundle().pathForResource("cable pressback", ofType: "mp4")
let url = NSURL.fileURLWithPath(path!)
let player = AVPlayer(URL: url)
playerViewController.player = player
playerViewController.view.frame = CGRectMake(0, 100, self.view.frame.size.width, 300)
playerViewController.view.translatesAutoresizingMaskIntoConstraints = true
view.addSubview(playerViewController.view)
self.addChildViewController(playerViewController)
[playerViewController .addObserver(self, forKeyPath:"videoBounds" , options: NSKeyValueObservingOptions.New, context: nil)]
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>)
{
print("playerViewController.view.frame = \(playerViewController.view.frame)")
if keyPath == "videoBounds"
{
let rect = change!["new"]! as! NSValue
if let newrect = rect.CGRectValue() as CGRect?
{
if newrect.width > 0 || newrect.height > 0
{
if avWidth > 0 || avHeight > 0
{
if newrect.width > avWidth || newrect.height > avHeight
{
print("Full Screen")
}
else if newrect.width < avWidth || newrect.height < avHeight
{
print("Normal screen")
}
}
avWidth = newrect.width
avHeight = newrect.height
}
}
}
}
However, it never seems to reach the code print("Full Screen")
.但是,它似乎永远不会到达代码
print("Full Screen")
。 It's hitting print("Normal Screen")
regardless of whether the player is in normal or full screen mode.无论播放器处于正常模式还是全屏模式,它都会点击
print("Normal Screen")
。
Thanks!谢谢!
Starting from iOS 12 we can use these AVPlayerViewControllerDelegate delegate methods :从 iOS 12 开始,我们可以使用这些AVPlayerViewControllerDelegate委托方法:
func playerViewController(AVPlayerViewController, willBeginFullScreenPresentationWithAnimationCoordinator: UIViewControllerTransitionCoordinator)
func playerViewController(AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator: UIViewControllerTransitionCoordinator)
Updated for Swift 3 :为 Swift 3 更新:
Add an observer for the playerViewController
object:为
playerViewController
对象添加一个观察者:
playerViewController(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"
{
if let rect = change?[.newKey] as? NSValue
{
if let newrect = rect.cgRectValue as CGRect?
{
// 200 is height of playerViewController in normal screen mode
if newrect.size.height <= 200
{
print("normal screen")
}
else
{
print("full screen")
}
}
}
}
}
Your code helped me handle switching between full screen and back.您的代码帮助我处理全屏和返回之间的切换。
But for the identification part, I just changed it slightly to my requirement.但是对于识别部分,我只是根据我的要求稍微更改了它。
let rect = change!["new"] as! NSValue
if let playerRect: CGRect = rect.CGRectValue() as CGRect {
if playerRect.size == UIScreen.mainScreen().bounds.size {
print("Video in full screen")
} else {
print("Video not in full screen")
}
}
Hope this helps.希望这可以帮助。
In iOS11 your screen's safe area will drop to 0 in the event of an AVPlayer going fullscreen.在 iOS11 中,如果 AVPlayer 全屏显示,您屏幕的安全区域将降至 0。 Though it might be an undocumented feature (and therefor potential bug).
虽然它可能是一个未记录的功能(因此有潜在的错误)。 I am having a hard time finding more info on it.
我很难找到有关它的更多信息。
[UIApplication sharedApplication].keyWindow.safeAreaLayoutGuide.layoutFrame.size.height == 0?
This is a slightly optimized Swift 4.2 version of @Pangu's answer.这是@Pangu 答案的略微优化的 Swift 4.2 版本。 It only detects the change, otherwise the observer is called also when interacting with the video like fast forwarding.
它只检测变化,否则在与视频交互(如快进)时也会调用观察者。 I also replaced the "videoBounds" with the
AVPlayerViewController.videoBounds
keypath to avoid the string and use the window bounds to determine if it's fullscreen or not.我还用
AVPlayerViewController.videoBounds
键路径替换了“videoBounds”以避免字符串并使用窗口边界来确定它是否是全屏的。
avPlayerViewController.addObserver(self, forKeyPath: #keyPath(AVPlayerViewController.videoBounds), options: [.old, .new], context: nil)
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == #keyPath(AVPlayerViewController.videoBounds) {
// detect only changes
if let oldValue = change?[.oldKey] as? CGRect, oldValue != CGRect.zero, let newValue = change?[.newKey] as? CGRect {
// no need to track the initial bounds change, and only changes
if !oldValue.equalTo(CGRect.zero), !oldValue.equalTo(newValue) {
if newValue.size.height < UIScreen.main.bounds.height {
print("normal screen")
} else {
print("fullscreen")
}
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.