Come chiudere ViewController in Swift?


214

Sto cercando di chiudere rapidamente un ViewController chiamando 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")
}

immagine casuale di un segue

Ho potuto vedere il messaggio println nell'output della console ma ViewController non viene mai respinto. Quale potrebbe essere il problema?


2
Come hai presentato il controller di visualizzazione?
dasdom,

Ho fatto la mappatura impostando un seguito - "show", vedi lo screenshot allegato.
rshankar,

4
Prova a usare modale. Se si utilizza push, è necessario ignorarlo con il metodo pop del controller di navigazione.
dasdom,

Risposte:


415

Dalla tua immagine sembra che tu abbia presentato ViewController usando push

Il dismissViewControllerAnimatedserve per chiudere ViewControllers che hanno presentato utilizzando modale

Swift 2

navigationController.popViewControllerAnimated(true)

Swift 4

navigationController?.popViewController(animated: true)

dismiss(animated: true, completion: nil)

6
Come lo faresti per un 'Show Detail' segue?
morale

2
Per Swift 2.2 navigationController! .PopViewControllerAnimated (true)
swiftBoy

7
Per Swift 3 navigationController! .PopViewController (animato: vero)
Alex Trott

175

Ho una soluzione per il tuo problema. Prova questo codice per chiudere il controller di visualizzazione se presenti la vista utilizzando modale:

Swift 3:

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

O

Se si presenta la vista usando "push" segue

self.navigationController?.popViewController(animated: true)

1
Grazie, ma sempre lo stesso risultato, non elimina
ViewController

4
In che modo differisce dal metodo utilizzato dall'OP?
dasdom,

30
La conversazione è inutile se non reagisci alle mie domande.
dasdom,

_ = self.navigationController? .popViewController (animato: vero)
valexa

19

se lo fai, suppongo che potresti non ricevere il messaggio println nella 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")
  }    
}

1
stackoverflow.com/questions/30840235/… . Qualsiasi aiuto, per favore? Sono bloccato per così tanto tempo che non riesco ancora a trovare una soluzione
Thiha Aung,

14

In Swift da 3.0 a 4.0 è facile come digitarlo nella tua funzione:

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

O se sei in un controller di navigazione puoi "pop":

self.navigationController?.popViewController(animated: true)

non funziona, perché sto usando pushViewController. Funziona solo self.navigationController? .PopViewController (animato: vero).
iOS

13
  1. incorporare la vista che si desidera eliminare in un NavigationController
  2. aggiungi un BarButton con "Fatto" come identificatore
  3. invoca l'Assistente editor con il pulsante Fine selezionato
  4. crea un IBAction per questo pulsante
  5. aggiungi questa linea tra parentesi:

    self.dismissViewControllerAnimated(true, completion: nil)

13

Uso:

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

invece di:

self.navigationController.dismissViewControllerAnimated(true, completion: nil)

1
aggiungere un ! al controller di navigazione e funziona per me
Jason G,

1
@naturalc: tieni presente che se navigationController è zero e hai messo!, l'app andrà in crash
jobima,

8

Se si presenta un controller senza un controller di navigazione, è possibile chiamare il seguente codice da un metodo del controller presentato.

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

Se il ViewController viene presentato in modo modale, presentatingController opzionale non sarà zero e il codice verrà eseguito.


mi hai salvato la giornata.
Shanu Singh,

6

Sulla base della mia esperienza, aggiungo un metodo per ignorarmi come estensione di 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)
        }
    }
}

Quindi chiamo questo metodo per chiudere il controller di visualizzazione in qualsiasi UIViewControllersottoclasse. Ad esempio, nell'azione Annulla:

class MyViewController: UIViewController {
   ...
   @IBAction func cancel(sender: AnyObject) {
     dismissMe(animated: true, completion: nil)
   }
   ...
}

6

Dalle documentazioni di Apple :

Il controller della vista di presentazione è responsabile del licenziamento del controller di vista che ha presentato

Pertanto, è una cattiva pratica invocare il metodo di rifiuto da solo.

Cosa dovresti fare se lo stai presentando modale è:

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

4

Non creare alcun seguito da Annulla o Fine ad altri VC e scrivi solo questo codice i tuoi pulsanti @IBAction

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

3

Ecco l'unico modo per chiudere il controller della vista corrente e tornare al controller della vista precedente. Puoi farlo solo tramite Storyboard.

  1. Apri storyboard
  2. Fare clic con il tasto destro del mouse sul pulsante Annulla e trascinarlo sul controller della vista precedente, dove si desidera tornare al controller precedente
  3. Ora rilascia il tasto destro e puoi vedere alcune azioni eseguite sul pulsante Annulla
  4. Ora scegli l'opzione "popover present" dalla lista
  5. Ora puoi chiudere la vista corrente facendo clic sul pulsante Annulla

Per favore, prova questo, sta lavorando con me.

Secondo modo - Usa - navigationController.popViewControllerAnimated(true)

Buona fortuna..


stackoverflow.com/questions/30840235/… . Qualsiasi aiuto, per favore? Sono bloccato per così tanto tempo che non riesco ancora a trovare una soluzione
Thiha Aung,

3
Questo è sbagliato. Non stai mai ignorando la vista che stai presentando invece un nuovo controller di visualizzazione in aggiunta a quello corrente, causando una perdita di memoria. Molto probabilmente questa verrà respinta dalla tua app store.
3366784,

2

Per riferimento, tenere presente che è possibile che si stia eliminando il controller di visualizzazione errato. Ad esempio, se si dispone di una casella di avviso o di una visualizzazione modale sopra un'altra modale. (Ad esempio, potresti avere un avviso di post su Twitter in cima all'attuale avviso modale). In questo caso, è necessario chiamare due volte licenziamento o utilizzare un svolgimento a seguire.


1

Se si presenta un ViewController in modo modale e si desidera tornare al ViewController root, fare attenzione a eliminare questo ViewController presentato in modo modale prima di tornare al ViewController root, altrimenti questo ViewController non verrà rimosso dalla memoria e causerà perdite di memoria.


1

In Swift 3.0

Se si desidera eliminare un controller di visualizzazione presentato

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

1

In Swift 4.1 e Xcode 9.4.1

Se si utilizza pushViewController per presentare un nuovo controller di visualizzazione, utilizzare questo

self.navigationController?.popViewController(animated: false)

Un'altra copia copia incolla
J. Doe,

1

Prova questo:

@IBAction func close() {
  dismiss(animated: true, completion: nil)
}

Il metodo chiamato "dismissViewController" richiede solo un singolo parametro, che suppongo sembrerebbe come eliminare l'animazione alla vista precedente, questa è la soluzione più semplice.
cassiodiego,

0

Questo codice scritto nell'azione del pulsante per chiudere

  @IBAction func cancel(sender: AnyObject) {
   dismiss(animated: true, completion: nil)
  }

1
Sebbene questo frammento di codice possa risolvere la domanda, inclusa una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che in futuro stai rispondendo alla domanda dei lettori e che queste persone potrebbero non conoscere i motivi del tuo suggerimento sul codice.
DimaSan,

0
@IBAction func back(_ sender: Any) {
        self.dismiss(animated: false, completion: nil)
    }

0

Se si utilizza il metodo presente nel VC principale, è necessario chiamare questa funzione, per chiudere il VC secondario, utilizzare questo

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

se si chiama VC figlio utilizzando il metodo push, per chiudere VC figlio, utilizzare questo

self.navigationController?.popViewController(animated: true)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.