0

我正在尝试向我的应用程序添加外部显示支持。该应用程序最初是使用 a 构建的AppDelegate,但我已将其迁移到使用 a SceneDelegate,因为我被告知它是 iOS 13 之后的外部显示支持所必需的。我更新了我的info.plist,既有SceneDelegate用于主应用程序的,也有ExtSceneDelegate用于外部的我在几个不同的教程中看到的显示。代表和 plist 更改都发布在下面。

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>
                </dict>
            </array>
            <key>UIWindowSceneSessionRoleExternalDisplay</key>
            <array>
                <dict>
                    <key>UISceneDelegateClassName</key>
                    <string>$(PRODUCT_MODULE_NAME).ExtSceneDelegate</string>
                    <key>UISceneConfigurationName</key>
                    <string>External Configuration</string>
                </dict>
            </array>
        </dict>
    </dict>

SceneDelegate.swift

import Foundation

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = scene as? UIWindowScene else { return }
        let window = UIWindow(windowScene: windowScene)
        
        // Provide your apps root view controller
        let initialViewController = RaiseBookViewController()
        window.rootViewController = initialViewController
        self.window = window
        window.makeKeyAndVisible()
    }
}

ExtSceneDelegate.swift

import Foundation

class ExtSceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = scene as? UIWindowScene else { return }
        let window = UIWindow(windowScene: windowScene)
        
        // Provide your apps root view controller
        let hostingController = HostingControllerPresentable(rootView: DefaultPresentationView(appIcon: Bundle.main.icon ?? UIImage()))
        window.rootViewController = hostingController
        self.window = window
        window.makeKeyAndVisible()
    }
}

在我的应用程序中,我想根据用户的活动更新外部显示器。为此,我像这样注册通知:

func registerForScreenNotifications() {
        let notificationCentre = NotificationCenter.default
        notificationCentre.addObserver(self, selector: #selector(self.externalScreenDidConnect(notification:)), name: UIScreen.didConnectNotification, object: nil)
    }

@objc func externalScreenDidConnect(notification: NSNotification) {
        guard let screen = notification.object as? UIScreen else {
            return
        }
        
        setupScreen(screen: screen, shouldRecurse: false)
    }

然后尝试设置连接的第二个显示器。

@objc func setupScreen(screen: UIScreen, shouldRecurse: Bool) {
        // For iOS13 find matching UIWindowScene
            var matchingWindowScene: UIWindowScene?
            if #available(iOS 13.0, *) {
                let scenes = UIApplication.shared.connectedScenes
                for aScene in scenes {
                    if let windowScene = aScene as? UIWindowScene {
                        // Look for UIWindowScene that has matching screen
                        if windowScene.screen == screen {
                            matchingWindowScene = windowScene
                            break
                        }
                    }
                }
                if matchingWindowScene == nil {
                    // UIWindowScene has not been created by iOS rendered yet
                    // Lets recall self after delay of two seconds
                    if true == shouldRecurse {
                        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
                            self.setupScreen(screen: screen, shouldRecurse: false)
                        }
                    }
                    // Dont proceed furthure in iOS13
                    return
                }
            }

            let vc = HostingControllerPresentable(rootView: DefaultPresentationView(appIcon: Bundle.main.icon ?? UIImage()))

            var externalWindow = UIWindow(frame: screen.bounds)
            externalWindow.rootViewController = vc
            if #available(iOS 13.0, *) {
                // Set windowScene here, no need to set screen
                externalWindow.windowScene = matchingWindowScene
            } else {
                // Set screen the traditional way
                externalWindow.screen = screen
            }
            externalWindow.isHidden = false
    }

按原样运行代码时,由于ExtSceneDelegate. 但是,如果我尝试更改外部显示器上显示的内容,该setupScreen功能将找不到任何匹配的显示器。如果我在仅返回一个元素处设置断点let scenes = UIApplication.shared.connectedScenes,即使实际上连接了两个显示器。我这辈子都想不通。并会感谢任何帮助。

注意:我知道在这段代码中,我试图在ExtSceneDelegatesetupScreen函数中为外部显示器设置相同的视图。我知道如果它正在工作,我不会注意到任何可见的变化,但我知道代码没有被执行,即使我尝试将它设置为不同的视图,也没有任何反应。

4

0 回答 0