C# 苹果电视作为iOS设备上的外部UI屏幕

C# 苹果电视作为iOS设备上的外部UI屏幕,c#,ios,apple-tv,uiscreen,external-display,C#,Ios,Apple Tv,Uiscreen,External Display,我有一个在子视图中显示视频的应用程序,如果能够在第二个屏幕(如苹果电视)上显示视频,并能够利用腾出的空间显示其他控件,那将是一件好事 关于如何做到这一点,我已经找到了各种各样的帮助,但我甚至在离开起跑门之前就遇到了困难 为了检测应用程序是否已在多显示环境中启动,所有示例代码都有一行,如 if (UIScreen.Screens.Length > 1) { // ... } (我用C#/Xamarin来做这件事,尽管我怀疑问题与此有关;无论如何,代码片段是用C#编写的) 我的问题是

我有一个在子视图中显示视频的应用程序,如果能够在第二个屏幕(如苹果电视)上显示视频,并能够利用腾出的空间显示其他控件,那将是一件好事

关于如何做到这一点,我已经找到了各种各样的帮助,但我甚至在离开起跑门之前就遇到了困难

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

if (UIScreen.Screens.Length > 1) {
    // ...
}
(我用C#/Xamarin来做这件事,尽管我怀疑问题与此有关;无论如何,代码片段是用C#编写的)

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

在应用程序运行时,还有几个观察者可以检测屏幕的添加/删除。我没有看到Xamarin的特定代码,但我认为它看起来像:

NSNotificationCenter.DefaultCenter.AddObserver(this, UIScreen.DidConnectNotification, NSKeyValueObservingOptions.New, IntPtr.Zero);
NSNotificationCenter.DefaultCenter.AddObserver(this, UIScreen.DidDisconnectNotification, NSKeyValueObservingOptions.New, IntPtr.Zero);
不管怎样,即使我在iPad上添加/删除苹果电视或进入/退出镜像模式,它们也不会启动

哦,;如果我这样做的话

avPlayer.AllowsExternalPlayback = true;
avPlayer.UsesExternalPlaybackWhileExternalScreenIsActive = true;
那么,这也会像预期的那样起作用。该视频现在在苹果电视上全屏显示,iPad上包含avPlayer的UIView变灰,而不是显示视频

然而,这不是我想要的。我想控制两个屏幕的布局,但这两个屏幕都没有。(虽然我确实希望苹果电视上的视频是全屏的,但我不希望它是一个AVPlayServices控制器,我确实希望重新利用iPad视频视图占据的屏幕空间)

在一天结束时,我想我所需要的就是设法得到

当我启动应用程序时,UIScreen.Screens.Length等于2


让UIScreen检测/报告第二次显示的秘密是什么?

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

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

虽然这看起来有点违反直觉,但实际上它使您的编码变得更简单;不管怎样,您都需要观察
UIScreenDidConnect
UIScreenDidConnect
通知,现在您不需要编写任何特殊代码来处理应用程序启动时已附加第二个屏幕的情况

您可以在
didfishLaunching
中使用类似的内容:

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
。比如:

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

然后你需要在屏幕上实现一个
OnScreenConnected
方法。

AirPlay似乎不赞成使用外部显示器。更实际地说,在我的iPad(运行iOS 11)上,镜像是控制中心唯一可用的选项。没有必要为Swift代码道歉。UIScreens在发布时只有一个项目是预期的,这一观点是有用的;这让我能够专注于为什么我没有看到通知。由于NSNotification.Name.UIScreenDidConnect可能是一个常量,您可以发布底层字符串是什么吗?C#和Swift代码在其他方面看起来完全相同,因此我传递的字符串似乎是潜在问题的候选字符串。它是“UIScreenDidConnectNotification”,尽管在Swift中使用的是
NSNotification.Name
枚举值。该字符串是枚举的原始值。看起来您对
AddObserver
使用了错误的格式-您使用的格式用于观察键/值。你想要