web-dev-qa-db-fra.com

Comment obtenir rootViewController avec iPadOS multi-fenêtres (SceneDelegate)?

J'utilise Xcode 11 (beta3) et je crée une application pour iOS 13. Dans mon projet, j'ai créé les méthodes déléguées pour UIWindowSceneDelegate en le déclarant dans Info.plist. Maintenant, je peux créer plusieurs fenêtres (et UIScene).

Comment puis-je accéder au rootViewController maintenant que je n'ai plus une seule fenêtre? J'en ai besoin pour obtenir une référence aux objets et aux limites qu'il contient.

Dans mon AppDelegate window is nil Et dans mon instance ViewController (contrôleur de vue enfant), j'ai essayé d'utiliser self.view.window.rootViewController Mais j'ai découvert que viewDidLoad() est trop tôt (je pense) et le la fenêtre est toujours nulle, fonctionne dans viewDidAppear(), mais je n'ai pas besoin de faire ce processus à chaque fois que le contrôleur de vue apparaît.

Quelle est la meilleure pratique avec cette nouvelle façon de gérer les scènes d'application?

Voici mon 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)
    }

Ma scène Délégué:

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

Vous avez maintenant plus d'un rootViewController, un pour chaque scène. Tout d'abord, vous devez répondre à celle dont vous avez besoin au moment de l'utilisation.

Vous souhaitez probablement obtenir l'un des rootViewController de la scène actuellement active, vous pouvez alors utiliser ceci:

        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.

Vous pouvez accéder aux scènes connectées en utilisant:

UIApplication.shared.connectedScenes

Selon documentation Apple :

Les scènes connectées sont celles qui sont en mémoire et qui font potentiellement un travail actif. Une scène connectée peut être au premier plan ou à l'arrière-plan, et elle peut être à l'écran ou hors écran.

Ensuite, vous pouvez les parcourir et essayer d'obtenir UIWindowScene à partir de là.

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

D'autre part, à partir du contrôleur de vue , vous pouvez accéder au window via le view:

self.view.window
2
P_O