Programlı olarak Swift'teki önceki ViewController'a geri dönün


211

Kullanıcıyı bir buton tıklamasıyla bir sayfaya gönderiyorum. Bu sayfa bir UITableViewController .

Şimdi kullanıcı bir hücreye dokunursa, onu bir önceki sayfaya geri itmek istiyorum.

Böyle bir şey düşündüm self.performSegue("back")....ama bu kötü bir fikir gibi görünüyor.

Bunu yapmanın doğru yolu nedir?


13
(doğru) self.navigationController .popViewControllerAnimated?
Kalpesh

Yanıtlar:


526

Hızlı 3:

Önceki görünüm denetleyicisine geri dönmek istiyorsanız

_ = navigationController?.popViewController(animated: true)

Kök görünüm denetleyicisine geri dönmek istiyorsanız

_ = navigationController?.popToRootViewController(animated: true)

1
Hücreye dokunduğunda verileri bir önceki Denetleyiciye nasıl geri gönderebilirim? navigationController? kullanıyorsak? .popViewControllerAnimated (true)
JDDelgado

4
@JDDelgado Verileri kullanıcıyla bu şekilde
Mohamad Kaakati

36
Swift 3 için.popViewController(animated: true)
Sasho

9
Herhangi bir uyarıyı susturmak için:_ = self.navigationController?.popToRootViewController(animated: true)
Andrew K

1
Dönüş değerini görmezden geliyoruz; _ = hızlı bir şekilde sözleşmedir.
Andrew K

53

Swift 3 , Swift 4

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

navigationController isteğe bağlıdır çünkü bir tane olmayabilir.


@Vyacheslva bir hata alıyorum "kapatma seft 'örtülü kullanımı, yakalama anlamlarını açık yapmak için' kendini 'kullanın"
Sandip Subedi

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

Bu yararlı oldu Ama navigasyon ile bazı değişkenler göndermek istiyorum Ama şimdi yapamam - kullandım override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vc = segue.destination as? Ama bunu kullanırken bunu kullanamam
Saeed Rahmatolahi

sonra navigationcontroller nasıl eklenir?
user25

@ user25 eklensin mi? ne demek istiyorsun?
Vyacheslav

37

Hızlı 3

Cevapta geç kalabilirim ama hızlı 3 için bunu şu şekilde yapabilirsiniz:

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
Bu 'tam olarak' doğru değil. Kendi navigasyonunu içeren bir görünüm denetleyicisi sunarsanız ve bir görünüm denetleyicisini ittikten sonra bu yöntemi kullandığınızda, dismiss:yalnızca geçerli görünüm denetleyicisini değil, aynı zamanda kök görünüm denetleyicisini de kapatır ve burada sorulan şey değildir.
Ernesto Fernandez

2
Soru, kullanıcının bir gezinme denetleyicisine sahip olup olmadığını sormadı. Bu, hiçbir navigasyon kontrolörü için en basit ve en iyi cevaptır. Bu gerçekten kabul edilen cevap olmalı.
Droid Chris

Teşekkürler Droid - Merhaba ernestofndz, rootVC'nin de reddedileceğini söyleyerek haklı olabilirsiniz, ancak bu benimle olmaz, sadece currentVC'yi reddeder, programlı olarak öğeleri ekleyip kaldırırım ve aynı yaklaşım olmayabilir. film şeridi üzerinde normal ekleme elemanları ile .. yanlışsam anlayışımı düzeltmek ... tableView için kullanıcı başka bir görünüm geçmek gerekiyorsa o zaman bu başka bir durumda ve ben ne yayınlanmıştır ve hiçbir bağlantı% 100 kabul edecek seninle .. ne ben bu durumda bir Geri düğmesi gerekli olduğunu anladım :)
Fullpower

belki u küçük bir giriş ekleyebilirsiniz .. çünkü yok işten çıkarma ve navigationController? .popViewController
marlonpya

dismiss(animated: true, completion: nil)rotasyondan sonra çalışmıyor!
user924

31

Hızlı 4

önceki ViewController'a geri dönmenin / geri dönmenin iki yolu vardır:

  1. İlk durum : kullandıysanız: self.navigationController?.pushViewController(yourViewController, animated: true) bu durumda kullanmanız gerekirself.navigationController?.popViewController(animated: true)
  2. İkinci durumda : kullandıysanız: self.present(yourViewController, animated: true, completion: nil) bu durumda kullanmanız gerekirself.dismiss(animated: true, completion: nil)

İlk durumda, ViewController'ınızı film şeridinizdeki bir navigationController'a katıştırdığınızdan emin olun


19

Bir sunulan durumda UIViewControllerbir içinden UIViewControlleryani ..

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

Sadece dismissfonksiyonu çağırın :

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

self.dismiss(animated: true)- rotasyondan sonra çalışmıyor
user924

17

hızlı 5 ve üstü

durum 1: Navigasyon denetleyicisi ile kullanma

self.navigationController?.popViewController(animated: true)

durum 2: mevcut görünüm denetleyicisi ile kullanma

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

11

Segue Tür 'Göster' veya 'Push' ise, UINavigationController Örneği üzerinde "popViewController (animated: Bool)" öğesini çağırabilirsiniz. Veya segue bir tür "mevcut" ise, UIViewController örneği ile "dismiss (animated: Bool, completion: (() -> Void)?)" Deyin


7

hızlı 3 için aşağıdaki kod satırını yazmanız yeterlidir

_ = navigationController?.popViewController(animated: true)

2

Bunu deneyin: önceki görünüm için şunu kullanın:

navigationController?.popViewController(animated: true)  

pop to root bu kodu kullanın:

navigationController?.popToRootViewController(animated: true) 

2

Son görünüm olarak TabViewController ile Swift 4.0 Xcode 10.0

Son ViewController TabViewController gömüldüyse, aşağıdaki kod sizi köke gönderir ...

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

Ama gerçekten son görünüme dönmek istiyorsanız (Tab1, Tab2 veya Tab3 görünümü olabilir) aşağıdaki kodu yazmanız gerekir:

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

Bu benim için çalışıyor, TabView biri sonra bir görünüm kullanıyordum :)


1

ViewController öğenizi film şeridindeki bir navigationController'a gömme ile ilgili sorular için:

  1. Farklı görünümünüzün denetleyicisinin bulunduğu film şeridinizi açın
  2. Gezinti denetleyicinizin başlamasını istediğiniz viewController öğesine dokunun
  3. Xcode'un üst kısmında "Editör" e hafifçe vurun
  4. -> Yerleştir'e dokunun
  5. -> "Navigasyon Denetleyicisi" ne dokunun

1

Bu benim için çalışıyor (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

Böyle yaptım

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

Bu soruna başka bir yaklaşım önermek istiyorum. Bir görünüm denetleyicisini açmak için gezinti denetleyicisini kullanmak yerine, çözme segueleri kullanın. Bu çözümün birkaç, ama gerçekten önemli avantajları var:

  1. Başlangıç ​​denetleyicisi, hedef hakkında hiçbir şey bilmeden başka bir hedef denetleyiciye (yalnızca öncekine değil) geri dönebilir.
  2. Push ve pop sekmeleri film şeridinde tanımlanır, bu nedenle görünüm denetleyicilerinizde gezinme kodu yoktur.

Daha fazla ayrıntıyı Adım Adım Çözme bölümünde bulabilirsiniz . Nasıl yapılır, verilerin nasıl geri gönderileceği de dahil olmak üzere önceki bağlantıda daha iyi açıklanır, ancak burada kısa bir açıklama yapacağım.

1) Varış yeri (başlangıç noktası değil) görünüm denetleyicisine gidin ve bir gevşeme sekmesi ekleyin:

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

2) CTRL'yi görünüm denetleyicisinin kendisinden başlangıç ​​görünümü denetleyicisindeki çıkış simgesine sürükleyin :

Görünüm denetleyicisinden gevşeyin

3) Birkaç dakika önce oluşturduğunuz çözme işlevini seçin:

Çözme işlevini seçin

4) Çözme segueini seçin ve bir isim verin:

Gevşeme segue adlandırma

5) Başlangıç ​​görünümü denetleyicisinin herhangi bir yerine gidin ve çözme segueini arayın:

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

Navigasyonunuz karmaşıklaşmaya başladığında bu yaklaşımın getirilerini çok fazla buldum.

Umarım bu birine yardımcı olur.


-3

Gezinti denetleyicisinin "viewDidDisappear" kodunu yazarak kök sayfaya yönlendirebilirim,

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


Bu, gezinme denetleyicisinin hiyerarşide ileri gitmek isteseniz bile köküne gelmesine neden olur.
bkSwifty
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.