web-dev-qa-db-ja.com

iPadOSマルチウィンドウ(SceneDelegate)でrootViewControllerを取得するにはどうすればよいですか?

私はXcode 11(beta3)を使用してiOS 13向けのアプリを構築しています。私のプロジェクトでは、Info.plistで宣言するUIWindowSceneDelegateのデリゲートメソッドを作成しました。これで、複数のウィンドウ(およびUIScene)を作成できます。

単一のウィンドウがなくなったので、どうすればrootViewControllerにアクセスできますか?保持しているオブジェクトと境界への参照を取得するために必要です。

私のAppDelegate _window is nil_と、ViewController(子ビューコントローラー)インスタンスで、_self.view.window.rootViewController_を使用してみましたが、viewDidLoad()はあまりにも早く(私はそう思います)、ウィンドウはまだnil、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
    }
_
11
Fabiosoft

これで、シーンごとに1つ以上のrootViewControllerができました。まず、使用時に必要なものに答える必要があります。

おそらく、現在アクティブなシーンのrootViewControllerの1つを取得したいのであれば、これを使用できます。

        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
        }
10
WILL K.

以下を使用して、接続されたシーンにアクセスできます。

UIApplication.shared.connectedScenes

Appleドキュメント に従って:

接続されたシーンは、メモリ内にあり、アクティブな作業を行っている可能性があるシーンです。接続されたシーンは、フォアグラウンドまたはバックグラウンドにあり、画面上または画面外にあります。

その後、それらを反復処理して、そこからUIWindowSceneを取得することができます。

guard let windowScene = (scene as? UIWindowScene) else { return }
print(windowScene.windows) // This will print windows associated with the scene.

一方、view controllerからは、windowviewを介してアクセスできます。

self.view.window
2
P_O