Програмно поверніться до попереднього ViewController у Swift


211

Я надсилаю користувача на сторінку, натиснувши кнопку. Ця сторінка є UITableViewController .

Тепер, якщо користувач натискає на клітинку, я хотів би повернути його на попередню сторінку.

Я думав про щось подібне, self.performSegue("back")....але це здається поганою ідеєю.

Який правильний спосіб це зробити?


13
self.navigationController? .popViewControllerAnimated (true)
Калпеш

Відповіді:


526

Швидкий 3:

Якщо ви хочете повернутися до попереднього контролера перегляду

_ = navigationController?.popViewController(animated: true)

Якщо ви хочете повернутися до контролера кореневого перегляду

_ = navigationController?.popToRootViewController(animated: true)

1
Як я можу повернути дані до попередньогоController, коли натисніть на комірку? якщо ми використовуємо navigationController? .popViewControllerAnimated (правда)
JDDelgado

4
@JDDelgado Це, як ви відправити назад дані з користувачем, stackoverflow.com/questions/12561735 / ...
Мохаммада Kaakati

36
Для Swift 3 це.popViewController(animated: true)
Сашо,

9
Щоб уникнути будь-яких попереджень:_ = self.navigationController?.popToRootViewController(animated: true)
Ендрю К

1
Ми ігноруємо повернуту вартість; _ = це швидка конвенція для цього.
Ендрю К

53

Swift 3 , Swift 4

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

navigationController необов’язковий, оскільки може бути не один.


@Vyacheslva Я отримую помилку "неявне використання" seft "у закритті, використовуйте" self ", щоб зробити явну семантику захоплення"
Sandip Subedi

@SandipSubedi використання [weak self]іself?.navigationController?.
В’ячеслав

це було корисно, але я хочу надіслати деякі змінні з навігацією, але тепер я не можу - я використовував, override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vc = segue.destination as? але коли я використовую, я не можу це використовувати
Saeed Rahmatolahi

як потім додати NaviController?
користувач25

@ user25 додати? Що ви маєте на увазі?
В’ячеслав

37

Швидкий 3

Я можу запізнитися у відповіді, але для швидкого 3 ви можете це зробити так:

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
Це не "повністю" правильно. Якщо ви представите контролер перегляду, який містить власну навігацію, і після натискання контролера перегляду скористайтеся цим методом, dismiss:він не відхилить поточний контролер перегляду, але і кореневий контролер перегляду, і це не те, що тут задавали.
Ернесто Фернандес

2
Питання не задавало питання, чи є у користувача контролер навігації. Це найпростіша і найкраща відповідь, якщо немає навігаційного контролера. Це справді має бути прийнятою відповіддю.
Дроїд Кріс

Спасибі Droid - Привіт ernestofndz, ви можете мати рацію, сказавши, що rootVC також буде відхилений, але зі мною цього не відбувається, він лише відхиляє поточний VC, я додаю та видаляю елементи програмно, і це може бути не той самий підхід з нормальним додаванням елементів на раскадровці .. виправте своє розуміння, якщо я помиляюся ... для tableView, якщо користувачеві потрібно передати деталі іншому перегляду, то це вже інший випадок і не має зв'язку з тим, що я розмістив, і я на 100% згоден з вами..що я зрозумів, що в цьому випадку потрібна кнопка "Назад" :)
Fullpower

можливо, ви можете додати трохи вступу .. тому що існують вивільнення та навігаціяController? .popViewController
marlonpya

dismiss(animated: true, completion: nil)не працює після обертання!
user924

31

Швидкий 4

Є два способи повернення / повернення до попереднього ViewController:

  1. Перший випадок : якщо ви використовували: self.navigationController?.pushViewController(yourViewController, animated: true) у цьому випадку вам потрібно скористатисяself.navigationController?.popViewController(animated: true)
  2. Другий випадок : якщо ви використовували: self.present(yourViewController, animated: true, completion: nil) у цьому випадку вам потрібно скористатисяself.dismiss(animated: true, completion: nil)

У першому випадку переконайтеся, що ви вбудували ViewController у навігаційний контролер у вашій дошці розкадрувань


19

У випадку, коли ви представили UIViewControllerзсередини UIViewControllerтобто.

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

Просто зателефонуйте до dismissфункції:

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

self.dismiss(animated: true)- не працює після обертання
user924

17

стрімкий 5 і вище

випадок 1: використання за допомогою навігаційного контролера

self.navigationController?.popViewController(animated: true)

випадок 2: використання з поточним контролером перегляду

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

11

Якщо Segue є видом "Show" або "Push", тоді ви можете викликати "popViewController (анімовані: Bool)" на екземпляр UINavigationController. Або якщо segue є своєрідним "присутнім", тоді зателефонуйте "відхилити (анімоване: Bool, завершення: (() -> недійсне)?" "З примірником UIViewController


7

для swift 3 просто потрібно написати наступний рядок коду

_ = navigationController?.popViewController(animated: true)

2

Спробуйте це: для попереднього перегляду використовуйте це:

navigationController?.popViewController(animated: true)  

спливати на root використовувати цей код:

navigationController?.popToRootViewController(animated: true) 

2

Swift 4.0 Xcode 10.0 з TabViewController як останній вид

Якщо ваш останній ViewController розміщений у TabViewController, наведений нижче код надішле вам корінь ...

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

Але якщо ви дійсно хочете повернутися до останнього перегляду (Це може бути Tab1, Tab2 або Tab3 view ..), ви повинні написати код нижче:

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

Це працює для мене, я використовував перегляд після одного з моїх TabView :)


1

З питань, як вбудувати свій viewController у Навігаційний Контролер у табло:

  1. Відкрийте рекламну дошку, де розташований ваш інший viewController
  2. Торкніться viewController, з якого ви хочете запустити ваш навігаційний контролер
  3. Угорі Xcode натисніть "Редактор"
  4. -> Торкніться вбудовування
  5. -> Натисніть "Контролер навігації

1

Цей працює для мене (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

Я зробив це так

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

Я хотів би запропонувати інший підхід до цієї проблеми. Замість використання навігаційного контролера для виведення контролера перегляду, використовуйте розмотані невістки. У цього рішення є кілька, але насправді важливих переваг:

  1. Контролер походження може повернутися до будь-якого іншого контролера призначення (не тільки попереднього), не знаючи нічого про місце призначення.
  2. Сегменти "Push" та "Pop" визначаються у табло, тому у контролерах перегляду немає коду навігації.

Ви можете знайти більш детальну інформацію в Відмотати перетікає крок за кроком . Як краще пояснити в попередньому посиланні, включаючи, як відправити дані назад, але тут я зроблю коротке пояснення.

1) Перейдіть до пункту призначення (не походження) контролера перегляду та додайте розмотаний вираз:

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

2) CTRL перетягнути з контролера уявлення самого на значок виходу в контролері уявлення походження:

Відмотайте від контролера перегляду

3) Оберіть функцію розкручування, яку ви створили кілька хвилин тому:

Виберіть функцію розмотування

4) Виберіть розмотаний мозок і дайте йому ім'я:

Називаючи розмотуючий сег

5) Перейдіть до будь-якого місця контролера подання джерела і зателефонуйте на розмотувальний мозок:

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

Я знайшов такий підхід, коли ваша навігація починає ускладнюватися.

Я сподіваюся, що це комусь допоможе.


-3

Я можу перенаправити на кореневу сторінку, записавши код у "viewDidDisappear" навігаційного контролера,

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


Це змушує контролер навігації спливати до кореня, навіть якщо ви хочете рухатися вперед в ієрархії.
bkSwifty
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.