如何在iOS 13上在不同的屏幕上显示不同的内容?

4
我有一个需要连接到外部显示器的应用程序,并且想要在两个屏幕上显示不同的内容(而不仅仅是镜像iPad屏幕)。
我尝试在我的Info.plist中添加了一个场景配置:
<key>UIApplicationSceneManifest</key>
<dict>
    <key>UIApplicationSupportsMultipleScenes</key>
    <true/>
    <key>UISceneConfigurations</key>
    <dict>
        <key>UIWindowSceneSessionRoleApplication</key>
        <array>
            <dict>
                <key>UISceneConfigurationName</key>
                <string>Default Configuration</string>
                <key>UISceneDelegateClassName</key>
                <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
                <key>UISceneStoryboardFile</key>
                <string>Main</string>
            </dict>
            <dict>
                <key>UISceneConfigurationName</key>
                <string>External Screen</string>
                <key>UISceneDelegateClassName</key>
                <string>$(PRODUCT_MODULE_NAME).ExtSceneDelegate</string>
                <key>UISceneStoryboardFile</key>
                <string>Ext</string>
            </dict>
        </array>
    </dict>
</dict>

我还添加了一个开关,以返回每个屏幕的正确UISceneConfiguration
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    switch connectingSceneSession.role.rawValue {
    case "UIWindowSceneSessionRoleApplication":
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    case "UIWindowSceneSessionRoleExternalDisplay":
        return UISceneConfiguration(name: "External Screen", sessionRole: connectingSceneSession.role)
    default:
        fatalError("No such role, I think? \(connectingSceneSession.role.rawValue)")
    }
}

在我AppDelegate中的configurationForConnecting代码中设置的断点确实会在我连接外部屏幕时被调用,但我的应用程序仍然只是镜像显示iPad屏幕。
我尝试按照this tutorial的步骤进行操作,但自从iOS 13以来,screen setter已经被弃用,因此该代码不起作用。
我真的不知道如何在不同的物理屏幕上显示不同的内容,有人能指点我一下吗?
2个回答

5
rmaddy的回答部分正确,不需要configurationForConnecting代码。但是我的Info.plist中有一个错误,错误在于我将两个配置都分配给了UIWindowSceneSessionRoleApplication角色。应该像这样:
<key>UIApplicationSceneManifest</key>
<dict>
    <key>UIApplicationSupportsMultipleScenes</key>
    <true/>
    <key>UISceneConfigurations</key>
    <dict>
        <key>UIWindowSceneSessionRoleApplication</key>
        <array>
            <dict>
                <key>UISceneConfigurationName</key>
                <string>Default Configuration</string>
                <key>UISceneDelegateClassName</key>
                <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
                <key>UISceneStoryboardFile</key>
                <string>Main</string>
            </dict>
        </array>
        <key>UIWindowSceneSessionRoleExternalDisplay</key>
        <array>
            <dict>
                <key>UISceneConfigurationName</key>
                <string>External Screen</string>
                <key>UISceneDelegateClassName</key>
                <string>$(PRODUCT_MODULE_NAME).ExtSceneDelegate</string>
                <key>UISceneStoryboardFile</key>
                <string>Ext</string>
            </dict>
        </array>
    </dict>
</dict>

外部屏幕配置位于UIWindowSceneSessionRoleExternalDisplay关键字下。

这个方法非常有效。为了让其充满整个屏幕,我必须将以下代码添加到我的ExtSceneDelegatewillConnectTo中:

DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
    windowScene.screen.overscanCompensation = .none
}

1
不错的发现。我看了你的 Info.plist 很多次,都没有注意到那个错误。 - rmaddy

2
如果您要在Info.plist中设置场景配置,请勿实现configurationForConnecting UIApplicationDelegate方法。因此,首先请注释掉该方法。
根据您的Info.plist设置,将自动为外部屏幕创建一个窗口场景。将为您创建ExtSceneDelegate类的实例,并将其与您的"Ext"故事板连接起来。
检查控制台是否有任何错误。如果您的场景配置或外部故事板存在任何问题,则只会看到主故事板的镜像,而不是外部故事板。
还请确保您在ExtSceneDelegate中实现的willConnectTo没有做任何阻止正确场景设置的事情。默认实现什么也不做就足以让您的外部故事板连接到在外部屏幕上自动创建的窗口。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接