web-dev-qa-db-fra.com

fonction unique pour ignorer tous les contrôleurs à vue ouverte

J'ai une application qui est une application à vue unique. J'ai un contrôleur de navigation relié à tous les contrôleurs enfants à partir du contrôleur de vue racine.

Dans chaque contrôleur enfant, j'ai un bouton de déconnexion. Je me demande si je peux appeler une seule fonction pour ignorer tous les contrôleurs ouverts en cours de route, quel que soit le contrôleur actuellement ouvert lorsque l'utilisateur clique sur la déconnexion.

Mon début de base:

func tryLogout(){
     self.dismissViewControllerAnimated(true, completion: nil)
     let navigationController = UINavigationController(rootViewController: UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("LoginViewController") )
     self.presentViewController(navigationController, animated: true, completion: nil)
}

Je cherche le moyen le plus efficace en termes de mémoire pour mener à bien cette tâche. Je vais mettre ma fonction de déconnexion dans un fichier utils séparé, mais je ne peux pas utiliser moi-même. Et j'ai toujours le problème de savoir quels contrôleurs licencier de manière dynamique.

Update Il a été suggéré de passer au contrôleur de vue racine. Donc, ma tentative est quelque chose comme:

func tryLogout(ViewController : UIViewController){
     print("do something")
     dispatch_async(dispatch_get_main_queue(), {
         ViewController.navigationController?.popToRootViewControllerAnimated(true)
         return
     })
 }

Serait-ce le meilleur moyen de réaliser ce que je recherche?

30
user2363025

Tu peux appeler : 

self.view.window!.rootViewController?.dismissViewControllerAnimated(false, completion: nil)

Devrait rejeter tous les contrôleurs de vue au-dessus du contrôleur de vue racine.

119
Liam

Réponse mise à jour pour Swift 3.2 et Swift 4

self.view.window!.rootViewController?.dismiss(animated: true, completion: nil)

et quand vous utilisez navigationController

self.navigationController?.popToRootViewController(animated: true)
19

Swift 4:

Pour éliminer tout résidu indésirable Modal ViewControllers, je l'ai utilisé et j'ai bien travaillé sans conserver aucune référence de pile de navigation.

UIApplication.shared.keyWindow?.rootViewController?.dismiss(animated: false, completion: nil)

self.view.window! s'est bloqué pour mon cas, probablement parce qu'il s'agit d'un écran modal et qu'il a perdu la référence à la fenêtre.

10
Naishta

Swift3

navigationController?.popToRootViewControllerAnimated(true)
9
markhorrocks

Jetez un coup d'œil à la façon dont les dérouleurs se déroulent. C’est très simple et vous permet de rejeter un certain contrôleur de vue dans la hiérarchie, même s’il s’agit d’une navigation complexe (contrôleurs de vues poussés et/ou présentés), sans trop de code.

Voici une très bonne réponse (de smilebot) qui montre comment utiliser les étapes de déroulement pour résoudre votre problème https://stackoverflow.com/a/27463286/503527

5
Nitin Alabur

fonctionne pour Swift 3.0 +

self.view.window!.rootViewController?.dismiss(animated: true, completion: nil)
0
Pardeep Kumar