Secara terprogram kembali ke ViewController sebelumnya di Swift

211

Saya mengirim pengguna ke halaman dengan mengklik tombol. Halaman ini adalah UITableViewController .

Sekarang jika pengguna mengetuk sel, saya ingin mendorongnya kembali ke halaman sebelumnya.

Saya memikirkan sesuatu seperti self.performSegue("back")....tapi ini sepertinya ide yang buruk.

Apa cara yang benar untuk melakukannya?

Kristen
sumber
13
self.navigationController? .popViewControllerAnimated (true)
Kalpesh

Jawaban:

527

Swift 3:

Jika Anda ingin kembali ke pengontrol tampilan sebelumnya

_ = navigationController?.popViewController(animated: true)

Jika Anda ingin kembali ke pengontrol tampilan root

_ = navigationController?.popToRootViewController(animated: true)
Praveen Gowda IV
sumber
1
Bagaimana saya bisa mengirim data kembali ke kontrol sebelumnya ketika sel diketuk? jika kita menggunakan navigationController? .popViewControllerAnimated (true)
JDDelgado
4
@JDDelgado Ini adalah bagaimana Anda mengirim data kembali dengan pengguna, stackoverflow.com/questions/12561735/...
Mohamad Kaakati
36
Untuk Swift 3 itu.popViewController(animated: true)
Sasho
9
Untuk menutup segala peringatan:_ = self.navigationController?.popToRootViewController(animated: true)
Andrew K
1
Kami mengabaikan nilai pengembalian; _ = adalah konvensi yang cepat untuk itu.
Andrew K
53

Swift 3 , Swift 4

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

navigationController adalah opsional karena mungkin tidak ada.

Vyacheslav
sumber
@Vyacheslva saya mendapatkan pesan kesalahan "penggunaan implisit 'seft' sebagai penutup, gunakan 'diri' untuk membuat semantik tangkap secara eksplisit"
Sandip Subedi
@SandipSubedi menggunakan [weak self]danself?.navigationController?.
Vyacheslav
ini berguna Tapi saya ingin mengirim beberapa variabel dengan navigasi Tapi sekarang saya tidak bisa - Saya menggunakan override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vc = segue.destination as? Tapi ketika saya menggunakan ini saya tidak bisa menggunakannya
Saeed Rahmatolahi
bagaimana cara menambahkan navigationController?
pengguna25
@ user25 tambahkan? maksud kamu apa?
Vyacheslav
37

Cepat 3

Saya mungkin terlambat dalam jawaban tetapi untuk swift 3 Anda dapat melakukannya dengan cara ini:

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)
}
Kekuatan penuh
sumber
3
Itu tidak sepenuhnya benar. Jika Anda menampilkan pengontrol tampilan yang berisi navigasi sendiri, dan setelah Anda mendorong pengontrol tampilan menggunakan metode dismiss:itu tidak hanya akan mengabaikan pengontrol tampilan saat ini, tetapi juga pengontrol tampilan root, dan bukan itu yang diminta di sini.
Ernesto Fernandez
2
Pertanyaannya tidak menanyakan apakah pengguna memiliki pengontrol navigasi. Ini adalah jawaban paling sederhana dan terbaik untuk tidak ada pengontrol navigasi. Ini benar-benar jawaban yang diterima.
Droid Chris
Terima kasih Droid - Hai ernestofndz, Anda mungkin benar mengatakan bahwa rootVC juga akan diberhentikan, tetapi ini tidak terjadi pada saya, itu hanya menghilangkan currentVC, saya menambahkan dan menghapus item secara program, dan mungkin tidak pendekatan yang sama dengan menambahkan elemen normal di storyboard .. perbaiki pemahaman saya jika saya salah ... untuk tableView jika pengguna perlu menyampaikan detail ke tampilan lain maka ini adalah kasus lain dan tidak memiliki keterkaitan dengan apa yang telah saya posting dan akan 100% setuju dengan Anda .. apa yang saya pahami adalah bahwa tombol Kembali diperlukan dalam kasus ini :)
Kekuatan penuh
mungkin kamu bisa menambahkan sedikit pengantar .. karena ada singkirkan & navigationController? .popViewController
marlonpya
dismiss(animated: true, completion: nil)tidak berfungsi setelah rotasi!
user924
31

Cepat 4

ada dua cara untuk kembali / kembali ke ViewController sebelumnya:

  1. Kasus pertama : jika Anda menggunakan: self.navigationController?.pushViewController(yourViewController, animated: true) dalam hal ini Anda harus menggunakanself.navigationController?.popViewController(animated: true)
  2. Kasus kedua : jika Anda menggunakan: self.present(yourViewController, animated: true, completion: nil) dalam hal ini Anda harus menggunakanself.dismiss(animated: true, completion: nil)

Dalam kasus pertama, pastikan Anda menyematkan ViewController Anda ke navigationController di storyboard Anda

Braham Youssef
sumber
19

Dalam hal Anda mempresentasikan UIViewControllerdari dalam UIViewControlleryaitu ..

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

Cukup panggil dismissfungsi:

// Other View Controller
self.dismiss(animated: true)
spencer.sm
sumber
self.dismiss(animated: true)- tidak berfungsi setelah rotasi
user924
17

cepat 5 dan di atas

kasus 1: menggunakan dengan pengontrol Navigasi

self.navigationController?.popViewController(animated: true)

kasus 2: menggunakan dengan controller tampilan sekarang

self.dismiss(animated: true, completion: nil)
midhun p
sumber
11

Jika Segue adalah Jenis 'Tampilkan' atau 'Dorong' maka Anda dapat memanggil "popViewController (animasi: Bool)" pada Instance of UINavigationController. Atau jika segue adalah jenis "sekarang" lalu panggil "singkirkan (animasi: Bool, selesai: (() -> Void)?)" Dengan instance UIViewController

Pankaj
sumber
7

untuk swift 3 Anda hanya perlu menulis baris kode berikut

_ = navigationController?.popViewController(animated: true)
Amr Angry
sumber
2

Coba ini: untuk tampilan sebelumnya gunakan ini:

navigationController?.popViewController(animated: true)  

pop to root menggunakan kode ini:

navigationController?.popToRootViewController(animated: true) 
Ahsan
sumber
2

Swift 4.0 Xcode 10.0 dengan TabViewController sebagai tampilan terakhir

Jika ViewController terakhir Anda tertanam dalam TabViewController, kode di bawah ini akan mengirim Anda ke root ...

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

Tetapi jika Anda benar-benar ingin kembali ke tampilan terakhir (Itu bisa menjadi tampilan Tab1, Tab2 atau Tab3 ..) Anda harus menulis kode di bawah ini:

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

Ini berfungsi untuk saya, saya menggunakan tampilan setelah salah satu dari TabView saya :)

Gabo MC
sumber
1

Untuk pertanyaan tentang cara menyematkan viewController Anda ke navigationController di storyboard:

  1. Buka storyboard Anda di mana viewController Anda yang berbeda berada
  2. Ketuk viewController Anda ingin pengontrol navigasi Anda untuk memulai
  3. Di bagian atas Xcode, ketuk "Editor"
  4. -> Ketuk embed
  5. -> Ketuk "Navigasi Kontroler
Manveer Singh Pandher
sumber
1

Yang ini berfungsi untuk saya (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")
        }
      }
    }
}
Igor Samtsevich
sumber
0

Saya melakukannya seperti ini

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)
}
Yaroslav Sarnitskiy
sumber
0

Saya ingin menyarankan pendekatan lain untuk masalah ini. Alih-alih menggunakan pengontrol navigasi untuk menampilkan pengontrol tampilan, gunakan segue bersantai. Solusi ini memiliki beberapa keuntungan, tetapi sangat penting,

  1. Pengontrol asal dapat kembali ke pengontrol tujuan lain (bukan hanya yang sebelumnya) tanpa mengetahui apa pun tentang tujuan.
  2. Segmen push dan pop didefinisikan dalam storyboard, jadi tidak ada kode navigasi di pengontrol tampilan Anda.

Anda dapat menemukan detail lebih lanjut di Unwind Segues Step-by-Step . Cara menjelaskan lebih baik di tautan sebelumnya, termasuk cara mengirim data kembali, tapi di sini saya akan membuat penjelasan singkat.

1) Pergi ke pengontrol tampilan tujuan (bukan asal) dan tambahkan segmen bersantai:

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

2) Seret CTRL dari pengontrol tampilan itu sendiri ke ikon keluar di pengontrol tampilan asal:

Lepas dari pengontrol tampilan

3) Pilih fungsi bersantai yang baru saja Anda buat beberapa saat yang lalu:

Pilih fungsi bersantai

4) Pilih segmen bersantai dan beri nama:

Menamai segue bersantai

5) Pergi ke tempat mana pun dari pengendali tampilan asal dan panggil segmen bersantai:

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

Saya telah menemukan pendekatan ini banyak hasil ketika navigasi Anda mulai menjadi rumit.

Saya harap ini membantu seseorang.

XME
sumber
-3

Saya dapat mengalihkan ke halaman root dengan menulis kode di "viewDidDisappear" dari navigated controller,

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

Mahe
sumber
Ini menyebabkan pengontrol navigasi pop ke root, bahkan jika Anda ingin bergerak maju dalam hierarki.
bkSwifty