Apple TV 作为 iOS 设备上的外部 UIScreen

Apple TV as an external UIScreen on an iOS device

我有一个在子视图中显示视频的应用程序,最好提供在第二个屏幕(例如 Apple TV)上显示该视频的选项,并能够使用释放出来的视频 space 以显示其他控件。

我找到了关于如何做到这一点的各种帮助,但我什至在走出起点门之前就碰壁了。

为了检测应用程序是否已在多显示环境中启动,所有示例代码都包含一行...

if (UIScreen.Screens.Length > 1) {
    // ...
}

(我在 C#/Xamarin 中执行此操作,但我怀疑问题与此有关;无论如何,代码片段在 C# 中)

我的问题是无论我做什么,屏幕数组始终为 1。 iPad 是 运行 iOS 11.2.5,如果我打开镜像,iPad 是镜像的,但是,同样,屏幕数组只有一个项目.

还有一些观察者检测到屏幕 added/removed 而应用 运行。我还没有看到 Xamarin 特定的代码,但我认为它看起来像:

NSNotificationCenter.DefaultCenter.AddObserver(this, UIScreen.DidConnectNotification, NSKeyValueObservingOptions.New, IntPtr.Zero);
NSNotificationCenter.DefaultCenter.AddObserver(this, UIScreen.DidDisconnectNotification, NSKeyValueObservingOptions.New, IntPtr.Zero);

无论如何,即使我 add/remove Apple TV 或 iPad 上的 enter/exit 镜像模式也不会启动。

哦;如果我这样做了

avPlayer.AllowsExternalPlayback = true;
avPlayer.UsesExternalPlaybackWhileExternalScreenIsActive = true;

那么这也按预期工作。视频现在在 Apple TV 上全屏显示,包含 avPlayer 的 iPad 上的 UIView 变灰而不是显示视频。

但是,这不是我要找的。我想控制两个屏幕的布局,但两者都没有。 (虽然我确实希望视频在 Apple TV 上全屏显示,但我不希望它成为 AVPlayerViewController,我确实想重新利用 iPad 视频视图占用的屏幕空间)

归根结底,我想我需要的只是设法获得

UIScreen.Screens.Length 在我启动应用程序时等于 2。

让 UIScreen 成为 detect/report 第二个显示器的秘诀是什么?

在已启用屏幕镜像的情况下启动应用程序时,UIScreen.screens 数组最初只包含设备的屏幕。启动后不久,iOS 会发布一条 UIScreenDidConnect 通知,告知您的应用已连接第二个屏幕。

启动时您将看到主屏幕的 captured 属性 如果启用了镜像,则为 true,但是您实际上无法访问第二个屏幕,直到通知发布后。请注意,captured 也可能表示正在进行屏幕录制。

虽然这看起来有点违反直觉,但它实际上使您的编码更简单;您需要观察 UIScreenDidConnectUIScreenDidDisconnect 通知 无论如何 现在您不需要编写任何特殊代码来处理应用程序启动的情况已连接第二个屏幕。

您可以在 didFinishLaunching:

中使用类似的内容
let nc = NotificationCenter.default

nc.addObserver(forName: NSNotification.Name.UIScreenDidConnect, object: nil, queue: nil) { (notification) in
    print("Screen connected")
    self.enableExternalDisplay()
}

nc.addObserver(forName: NSNotification.Name.UIScreenDidDisconnect, object: nil, queue: nil) { (notification) in
    print("Screen disconnected")
    self.disableExternalDisplay()
}

更新

实际上,当您真正想要通知观察时,看起来您的代码中有 AddObserver 的 key/value 观察格式。类似于:

NSNotificationCenter.DefaultCenter.AddObserver(UIScreen.DidConnectNotification,OnScreenConnected)

然后你需要实现一个OnScreenConnected方法。