Torna a livello di programmazione al ViewController precedente in Swift


211

Mando l'utente su una pagina con un clic del pulsante. Questa pagina è un UITableViewController .

Ora se l'utente tocca una cella, vorrei riportarlo alla pagina precedente.

Ho pensato a qualcosa del genere, self.performSegue("back")....ma questa sembra essere una cattiva idea.

Qual è il modo corretto di farlo?


13
self.navigationController? .popViewControllerAnimated (true)
Kalpesh

Risposte:


527

Swift 3:

Se si desidera tornare al controller della vista precedente

_ = navigationController?.popViewController(animated: true)

Se si desidera tornare al controller della vista principale

_ = navigationController?.popToRootViewController(animated: true)

1
Come posso inviare i dati al controllore precedente quando si tocca la cella? se stiamo usando navigationController? .popViewControllerAnimated (true)
JDDelgado

4
@JDDelgado Questo è il modo di inviare la parte posteriore dei dati con l'utente, stackoverflow.com/questions/12561735/...
Mohamad Kaakati

36
Per Swift 3 è.popViewController(animated: true)
Sasho,

9
Per eliminare eventuali avvisi:_ = self.navigationController?.popToRootViewController(animated: true)
Andrew K,

1
Stiamo ignorando il valore di ritorno; _ = è la convenzione rapida per quello.
Andrew K,

53

Swift 3 , Swift 4

if movetoroot { 
    navigationController?.popToRootViewController(animated: true)
} else {
    navigationController?.popViewController(animated: true)
}

navigationController è facoltativo perché potrebbe non essercene uno.


@Vyacheslva sto ricevendo un errore "uso implicito di 'seft' in chiusura, usare 'self' per rendere esplicita la semantica della cattura"
Sandip Subedi

@SandipSubedi use [weak self]andself?.navigationController?.
Vyacheslav

questo è stato utile Ma voglio inviare alcune variabili con la navigazione Ma ora non posso - l'ho usato override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vc = segue.destination as? Ma quando lo uso non posso usarlo
Saeed Rahmatolahi

come aggiungere navigationController quindi?
user25

@utente25 aggiungere? cosa intendi?
Vyacheslav,

37

Swift 3

Potrei essere in ritardo nella risposta, ma per Swift 3 puoi farlo in questo modo:

override func viewDidLoad() {
    super.viewDidLoad()

    navigationItem.leftBarButtonItem = UIBarButtonItem(title: "< Back", style: .plain, target: self, action: #selector(backAction))

    // Do any additional setup if required.
}

func backAction(){
    //print("Back Button Clicked")
    dismiss(animated: true, completion: nil)
}

3
Non è "pienamente" corretto. Se si presenta un controller di visualizzazione che contiene la propria navigazione e dopo aver premuto un controller di visualizzazione, si utilizza questo metodo dismiss:non solo per chiudere il controller di visualizzazione corrente, ma anche per il controller di visualizzazione principale e non è ciò che è stato richiesto qui.
Ernesto Fernandez,

2
La domanda non chiedeva se l'utente avesse un controller di navigazione. Questa è la risposta più semplice e migliore per nessun controller di navigazione. Questa dovrebbe davvero essere la risposta accettata.
Droid Chris,

Grazie Droid - Ciao ernestofndz, potresti avere ragione nel dire che anche il rootVC verrà respinto, ma questo non accade con me, elimina solo il CurrentVC, sto aggiungendo e rimuovendo gli oggetti a livello di codice e potrebbe non essere lo stesso approccio con i normali elementi aggiunti sullo storyboard .. correggo la mia comprensione se sbaglio ... per la tabellaVisualizza se l'utente deve passare i dettagli a un'altra vista, questo è un altro caso e non ha alcun collegamento con ciò che ho pubblicato e sarà d'accordo al 100% con te ... quello che ho capito è che in questo caso è richiesto un pulsante Indietro :)
Fullpower

forse puoi aggiungere una piccola introduzione .. perché esistono licenziamento e navigazioneController? .popViewController
marlonpya

dismiss(animated: true, completion: nil)non funziona dopo la rotazione!
user924

31

Swift 4

ci sono due modi per tornare / tornare al ViewController precedente:

  1. Primo caso : se hai usato: self.navigationController?.pushViewController(yourViewController, animated: true) in questo caso devi usareself.navigationController?.popViewController(animated: true)
  2. Secondo caso : se hai usato: self.present(yourViewController, animated: true, completion: nil) in questo caso devi usareself.dismiss(animated: true, completion: nil)

Nel primo caso, assicurati di aver incorporato ViewController in un NavigationController nello storyboard


19

Nel caso in cui hai presentato un UIViewControllerda all'interno di un UIViewControllerie ..

// Main View Controller
self.present(otherViewController, animated: true)

Basta chiamare la dismissfunzione:

// Other View Controller
self.dismiss(animated: true)

self.dismiss(animated: true)- non funziona dopo la rotazione
user924

17

rapido 5 e superiore

caso 1: utilizzo con il controller di navigazione

self.navigationController?.popViewController(animated: true)

caso 2: utilizzo con il controller della vista corrente

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

11

Se Segue è un tipo di "Show" o "Push", è possibile richiamare "popViewController (animato: Bool)" su Instance of UINavigationController. O se segue è una specie di "presente", allora chiama "respingi (animato: Bool, completamento: (() -> Void)?)" Con istanza di UIViewController


7

per Swift 3 devi solo scrivere la seguente riga di codice

_ = navigationController?.popViewController(animated: true)

2

Prova questo: per la vista precedente usa questo:

navigationController?.popViewController(animated: true)  

pop to root usa questo codice:

navigationController?.popToRootViewController(animated: true) 

2

Swift 4.0 Xcode 10.0 con un TabViewController come ultima vista

Se il tuo ultimo ViewController è incorporato in un TabViewController, il codice seguente ti invierà al root ...

navigationController?.popToRootViewController(animated: true)
navigationController?.popViewController(animated: true)

Ma se vuoi davvero tornare all'ultima vista (che potrebbe essere la vista Tab1, Tab2 o Tab3 ..) devi scrivere il codice seguente:

_ = self.navigationController?.popViewController(animated: true)

Questo funziona per me, stavo usando una vista dopo uno dei miei TabView :)


1

Per domande su come incorporare il tuo ViewController in un NavigationController nello storyboard:

  1. Apri lo storyboard in cui si trovano i diversi viewController
  2. Tocca il viewController da cui desideri avviare il controller di navigazione
  3. Nella parte superiore di Xcode, tocca "Editor"
  4. -> Toccare incorpora
  5. -> Toccare "Controller di navigazione

1

Questo funziona per me (Swift UI)

struct DetailView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

  var body: some View {
      VStack {
        Text("This is the detail view")
        Button(action: {
          self.presentationMode.wrappedValue.dismiss()
        }) {
          Text("Back")
        }
      }
    }
}

0

L'ho fatto così

func showAlert() {
    let alert = UIAlertController(title: "Thanks!", message: "We'll get back to you as soon as posible.", preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
        self.dismissView()
    }))

    self.present(alert, animated: true)
}

func dismissView() {
    navigationController?.popViewController(animated: true)
    dismiss(animated: true, completion: nil)
}

0

Vorrei suggerire un altro approccio a questo problema. Invece di utilizzare il controller di navigazione per far apparire un controller di visualizzazione, utilizzare segui Unind. Questa soluzione presenta alcuni vantaggi, ma davvero importanti:

  1. Il controller di origine può tornare a qualsiasi altro controller di destinazione (non solo quello precedente) senza sapere nulla della destinazione.
  2. I follower push e pop sono definiti nello storyboard, quindi nessun codice di navigazione nei controller di visualizzazione.

Puoi trovare maggiori dettagli in Unwind Segues Step-by-Step . Il come si spiega meglio nel precedente link, incluso come inviare i dati indietro, ma qui farò una breve spiegazione.

1) Vai al controller di visualizzazione della destinazione (non dell'origine) e aggiungi un svolgitore segue:

    @IBAction func unwindToContact(_ unwindSegue: UIStoryboardSegue) {
        //let sourceViewController = unwindSegue.source
        // Use data from the view controller which initiated the unwind segue
    }

2) Trascinamento CTRL dal controller di visualizzazione stesso all'icona di uscita nel controller di visualizzazione dell'origine:

Rilassati dal controller di visualizzazione

3) Seleziona la funzione di svolgimento che hai appena creato pochi istanti fa:

Seleziona la funzione di svolgimento

4) Seleziona lo svolgimento che segue e assegnagli un nome:

Il nome unfind segue

5) Vai in qualsiasi punto del controller della vista di origine e chiama lo svolgimento seguente:

performSegue(withIdentifier: "unwindToContact", sender: self)

Ho trovato molto utili questi approcci quando la tua navigazione inizia a complicarsi.

Spero che questo aiuti qualcuno.


-3

Posso reindirizzare alla pagina principale scrivendo il codice in "viewDidDisappear" del controller navigato,

override func viewDidDisappear(_ animated: Bool) { self.navigationController?.popToRootViewController(animated: true) }


Questo fa sì che il controller di navigazione passi alla radice, anche se si desidera andare avanti nella gerarchia.
bkSwifty,
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.