Comment ignorer ViewController dans Swift?

214

J'essaie de rejeter un ViewController rapidement en appelant dismissViewControllerunIBAction

  @IBAction func cancel(sender: AnyObject) {
    self.dismissViewControllerAnimated(false, completion: nil)
    println("cancel")
}

@IBAction func done(sender: AnyObject) {
    self.dismissViewControllerAnimated(false, completion: nil)
    println("done")
}

image aléatoire d'une séquence

Je pouvais voir le message println dans la sortie de la console mais ViewController n'est jamais rejeté. Quel pourrait être le problème?

rshankar
la source
2
Comment avez-vous présenté le contrôleur de vue?
dasdom
J'ai fait le mappage en définissant un segue - "show", voir la capture d'écran ci-jointe.
rshankar
4
Essayez d'utiliser le modal. Si vous utilisez push, vous devez le supprimer avec la méthode pop du contrôleur de navigation.
dasdom

Réponses:

415

De votre image, il semble que vous ayez présenté le ViewController à l'aide de push

Le dismissViewControllerAnimatedest utilisé pour fermer les ViewControllers présentés à l'aide de modal

Swift 2

navigationController.popViewControllerAnimated(true)

Swift 4

navigationController?.popViewController(animated: true)

dismiss(animated: true, completion: nil)
Zoon Nooz
la source
6
Comment feriez-vous pour un enchaînement «Show Detail»?
MoralCode
2
Pour Swift 2.2 navigationController! .PopViewControllerAnimated (true)
swiftBoy
7
Pour Swift 3 navigationController! .PopViewController (animé: vrai)
Alex Trott
175

J'ai une solution à votre problème. Veuillez essayer ce code pour fermer le contrôleur de vue si vous présentez la vue à l'aide de modal:

Swift 3:

self.dismiss(animated: true, completion: nil)

OU

Si vous présentez la vue à l'aide d'une séquence "push"

self.navigationController?.popViewController(animated: true)
satheesh
la source
1
Merci, mais toujours le même résultat, il ne rejette pas le ViewController
rshankar
4
En quoi est-ce différent de la méthode utilisée par l'OP?
dasdom
30
La conversation est inutile si vous ne réagissez pas à mes questions.
dasdom
_ = self.navigationController? .popViewController (animé: vrai)
valexa
19

si vous faites cela, je suppose que vous n'obtiendrez peut-être pas de message println dans la console,

@IBAction func cancel(sender: AnyObject) {
  if(self.presentingViewController){
    self.dismissViewControllerAnimated(false, completion: nil)
    println("cancel")
   }
}

@IBAction func done(sender: AnyObject) {
  if(self.presentingViewController){
    self.dismissViewControllerAnimated(false, completion: nil)
    println("done")
  }    
}
BaSha
la source
1
stackoverflow.com/questions/30840235/… . Toute aide, s'il vous plaît? Je suis coincé à cela depuis si longtemps qui ne trouve toujours pas de solution
Thiha Aung
14

Dans Swift 3.0 à 4.0, c'est aussi simple que de taper ceci dans votre fonction:

self.dismiss(animated: true, completion: nil)

Ou si vous êtes dans un contrôleur de navigation, vous pouvez le "pop":

self.navigationController?.popViewController(animated: true)
Chase McElroy
la source
rejeter ne fonctionne pas, car j'utilise pushViewController. Seul self.navigationController? .PopViewController (animé: vrai) fonctionne.
iOS
13
  1. intégrer la vue que vous souhaitez supprimer dans un NavigationController
  2. ajouter un BarButton avec "Done" comme identifiant
  3. appeler l'assistant éditeur avec le bouton Terminé sélectionné
  4. créer une IBAction pour ce bouton
  5. ajoutez cette ligne entre crochets:

    self.dismissViewControllerAnimated(true, completion: nil)
ARTS LAOMUSIQUES
la source
13

Utilisation:

self.dismiss(animated: true, completion: nil)

au lieu de:

self.navigationController.dismissViewControllerAnimated(true, completion: nil)
jobima
la source
1
ajouter un ! à la navigationController et cela fonctionne pour moi
Jason G
1
@naturalc: sachez que si navigationController est nul et que vous mettez!, l'application se bloquera
jobima
8

Si vous présentez un contrôleur sans contrôleur de navigation, vous pouvez appeler le code suivant à partir d'une méthode du contrôleur présenté.

self.presentingViewController?.dismiss(animated: true, completion: nil)

Si votre ViewController est présenté de manière modale, la présentation facultative de ViewController ne sera pas nulle et le code sera exécuté.

Peyotle
la source
tu m'as sauvé la journée.
Shanu Singh
6

Sur la base de mon expérience, j'ajoute une méthode pour me rejeter en tant qu'extension de UIViewController:

extension UIViewController {
    func dismissMe(animated: Bool, completion: (()->())?) {
        var count = 0
        if let c = self.navigationController?.viewControllers.count {
            count = c
        }
        if count > 1 {
            self.navigationController?.popViewController(animated: animated)
            if let handler = completion {
                handler()
            }
        } else {
            dismiss(animated: animated, completion: completion)
        }
    }
}

Puis j'appelle cette méthode pour rejeter le contrôleur de vue dans n'importe quelle UIViewControllersous-classe. Par exemple, dans l'action d'annulation:

class MyViewController: UIViewController {
   ...
   @IBAction func cancel(sender: AnyObject) {
     dismissMe(animated: true, completion: nil)
   }
   ...
}
David.Chu.ca
la source
6

Depuis les documentations Apple :

Le contrôleur de vue présentateur est responsable du rejet du contrôleur de vue qu'il a présenté.

Ainsi, c'est une mauvaise pratique de simplement invoquer la méthode de rejet de lui-même.

Ce que vous devez faire si vous le présentez modal, c'est:

presentingViewController?.dismiss(animated: true, completion: nil)
OhadM
la source
4

Ne créez aucun enchaînement depuis Annuler ou Terminé vers un autre VC et écrivez uniquement ce code avec vos boutons @IBAction

@IBAction func cancel(sender: AnyObject) {
    dismiss(animated: false, completion: nil)
}
Fatih
la source
3

Voici une façon de supprimer le contrôleur de vue actuel et de revenir au contrôleur de vue précédent. Vous pouvez le faire via Storyboard uniquement.

  1. Storyboard ouvert
  2. Faites un clic droit sur le bouton Annuler et faites-le glisser vers le contrôleur de vue précédent, où vous souhaitez revenir au contrôleur précédent
  3. Maintenant, relâchez le clic droit et vous pouvez voir certaines actions qui s'exécutent sur le bouton Annuler
  4. Maintenant, choisissez l'option "popover present" de la liste
  5. Vous pouvez maintenant fermer votre vue actuelle en cliquant sur le bouton Annuler

S'il vous plaît essayez ceci, ça fonctionne avec moi.

Deuxième voie - Utilisation - navigationController.popViewControllerAnimated(true)

Bonne chance ..

Chetan Bhalara
la source
stackoverflow.com/questions/30840235/… . Toute aide, s'il vous plaît? Je suis coincé à cela depuis si longtemps qui ne trouve toujours pas de solution
Thiha Aung
3
C'est faux. Vous n'écartez jamais la vue que vous présentez à la place un nouveau contrôleur de vue au-dessus de l'actuel, provoquant une fuite de mémoire. Cela entraînera très probablement le rejet de votre application sur l'App Store.
3366784
2

Pour référence, sachez que vous rejetez peut-être le mauvais contrôleur de vue. Par exemple, si vous avez une boîte d'alerte ou un modal affiché au-dessus d'un autre modal. (Vous pouvez avoir une alerte de publication Twitter s'affichant au-dessus de votre alerte modale actuelle, par exemple). Dans ce cas, vous devez appeler le renvoi deux fois ou utiliser une séquence de déroulement.

mcfroob
la source
1

Si vous présentez un ViewController de manière modale et que vous souhaitez revenir au ViewController racine, veillez à ignorer ce ViewController présenté de façon modale avant de revenir au ViewController racine sinon ce ViewController ne sera pas supprimé de la mémoire et entraînera des fuites de mémoire.

dan
la source
1

Dans Swift 3.0

Si vous souhaitez supprimer un contrôleur de vue présenté

self.dismiss(animated: true, completion: nil)
Ramakrishna
la source
1

Dans Swift 4.1 et Xcode 9.4.1

Si vous utilisez pushViewController pour présenter un nouveau contrôleur de vue, utilisez ceci

self.navigationController?.popViewController(animated: false)
iOS
la source
Une autre réponse de copier-coller
J. Doe
1

Essaye ça:

@IBAction func close() {
  dismiss(animated: true, completion: nil)
}
cassiodiego
la source
La méthode appelée "disableViewController" ne prend qu'un seul paramètre, ce qui, je suppose, ressemblerait à ignorer l'animation de la vue précédente, c'est la solution la plus simple.
cassiodiego
1

Étant donné que vous avez utilisé viewController présenté par push, vous pouvez donc utiliser

self.dismiss(animated: false, completion: nil)
Ionique
la source
0

Ce code écrit en action de bouton pour ignorer

  @IBAction func cancel(sender: AnyObject) {
   dismiss(animated: true, completion: nil)
  }
Sai kumar Reddy
la source
1
Bien que cet extrait de code puisse résoudre la question, y compris une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondrez à la question des lecteurs à l'avenir et que ces personnes ne connaissent peut-être pas les raisons de votre suggestion de code.
DimaSan
0
@IBAction func back(_ sender: Any) {
        self.dismiss(animated: false, completion: nil)
    }
eng mohamed emam
la source
0

Si vous utilisez la méthode actuelle dans le VC parent, vous devez appeler cette fonction, pour ignorer le VC enfant, utilisez cette

self.dismiss(animated: true, completion: nil)

si vous appelez le VC enfant à l'aide de la méthode push, pour rejeter le VC enfant, utilisez ce

self.navigationController?.popViewController(animated: true)
Фаррух Махмудов
la source