Как получить rootViewController с мультиокном iPadOS (SceneDelegate)?

Я использую Xcode 11 (бета3) и создаю приложение для iOS 13. В моем проекте я создал методы делегата для UIWindowSceneDelegate объявив это в Info.plist. Теперь я могу создать несколько окон (и UIScene).

Как я могу получить доступ к rootViewController теперь у меня больше нет ни одного окна? Мне нужно, чтобы получить ссылку на объекты и границы, которые он содержит.

В моем AppDelegate window is nilи в моем экземпляре ViewController (дочерний контроллер представления) я пытался использовать self.view.window.rootViewController но я узнал, что viewDidLoad() слишком рано (я думаю) и окно все еще ноль, работает в viewDidAppear(), но мне не нужно делать этот процесс каждый раз, когда появляется контроллер представления.

Какова лучшая практика с этим новым способом обработки сцен приложения?

Вот мой AppDelegate:

func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
        return true
    }

    func application(_ application: UIApplication,
                     configurationForConnecting connectingSceneSession: UISceneSession,
                     options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

Мой SceneDelegate:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // yes it's empty, I'm using storyboard
    }

2 ответа

Теперь у вас есть более одного rootViewController, по одному для каждой сцены. Во-первых, вы должны ответить, какой вам нужен в момент использования.

Вероятно, вы хотите получить один из rootViewController текущей активной сцены, тогда вы можете использовать это:

        var rootVC:UIViewController? = nil
        if #available(iOS 13.0, *) {
            for scene in UIApplication.shared.connectedScenes {
                if scene.activationState == .foregroundActive {
                    rootVC = ((scene as? UIWindowScene)!.delegate as! UIWindowSceneDelegate).window!!.rootViewController
                    break
                }
            }
        } else {
            // Fallback on earlier versions
        }

Вы можете получить доступ к подключенным сценам через

UIApplication.shared.connectedScenes

Согласно документации Apple

Подключенные сцены - это те, которые находятся в памяти и потенциально выполняют активную работу. Подключенная сцена может находиться на переднем плане или на заднем плане, а также на экране или за экраном.

Тогда вы можете перебирать их и пытаться получить UIWindowScene оттуда.

guard let windowScene = (scene as? UIWindowScene) else { return }

print(windowScene.windows) // this will print windows associated with the scene.

С другой стороны, из контроллера представления вы можете получить доступ к окну через представление:

self.view.window
Другие вопросы по тегам