web-dev-qa-db-fra.com

Swift 4 Tentative de présentation de ViewController dont la vue n'est pas dans la hiérarchie des fenêtres

J'utilise Swift 4 et j'essaie de créer un alertView lorsqu'il y a une erreur lors de l'inscription d'un utilisateur à l'aide de Firebase. J'ai un IBAction pour le bouton d'inscription qui signera l'utilisateur en utilisant le texte de deux textfields, un pour l'email et un pour le mot de passe.

J'essaie essentiellement d'afficher un alertview quand il y a une erreur avec le processus d'inscription, par exemple il y a un textfield vide.

enter image description here

J'ai joint une capture d'écran de la fonction à l'endroit où cela se produit. Je sais que j'obtiens en fait une erreur car l'instruction print génère une erreur s'il y en a une.

Peu importe s'il y a une erreur ou non, aucune vue d'alerte ne s'affiche et l'application effectue la transition malgré tout.

2019-01-15 21: 40: 26.368924-0500 Pronto [9036: 225268] Avertissement: tentative de présentation sur la vue dont la vue n'est pas dans la hiérarchie des fenêtres

C'est la sortie que j'obtiens pour l'alerte qui s'affiche maintenant. J'ai regardé tous les autres messages sur ce même problème, mais aucun ne semble fonctionner.

3
Steve Sahayadarlin

Ce problème se produit en raison de votre hiérarchie de vues.

Vous devez savoir quel est votre contrôleur de vue actuel/le plus haut dans la hiérarchie des vues et présenter votre alerte dessus.

Pour trouver le contrôleur de vue le plus haut, utilisez le code suivant:

func getTopMostViewController() -> UIViewController? {
    var topMostViewController = UIApplication.shared.keyWindow?.rootViewController

    while let presentedViewController = topMostViewController?.presentedViewController {
        topMostViewController = presentedViewController
    }

    return topMostViewController
}

Et présentez votre alerte sur le contrôleur de vue le plus haut et utilisez le thread principal pour présenter une alerte car les fermetures peuvent avoir fonctionné sur un autre thread.

DispatchQueue.main.async { 
    getTopMostViewController()?.present(alertController, animated: true, completion: nil)
}

Veuillez vous référer à cette réponse de pile: Swift 3 Tenter de présenter dont la vue n'est pas dans la hiérarchie des fenêtres

18
Jarvis The Avenger

Essayez d'utiliser ViewDidAppear au lieu de View did Load.

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    let alertViewController = UIAlertController(title: "Any", message: "Any Custom Message", preferredStyle: .alert)

    alertController.addAction(UIAlertAction(title: "ANy", style: .cancel, handler: nil))
    present(alertViewController, animated: true, completion: nil)
}
1
Mayank Wadhwa

Vous pouvez obtenir le contrôleur de vue le plus haut et faire en sorte que ce contrôleur de vue présente l'alerte. Donc au lieu de self.present utilisez cette approche et voyez si cela fonctionne:

let topViewController = UIApplication.shared.keyWindow?.rootViewController
topViewController?.present(alertController, animated: true, completion: nil)

Essayez également de présenter sur le thread principal, car vous essayez d'afficher l'alerte dans le gestionnaire d'achèvement createUser:

DispatchQueue.main.async { 
    self.present(alertController, animated: true, completion: nil)
}
0