Программно вернуться к предыдущему ViewController в Swift
Я отправляю пользователя на страницу одним нажатием кнопки. Эта страница является UITableViewController.
Теперь, если пользователь нажимает на ячейку, я бы хотел вернуть его на предыдущую страницу.
Я думал о чем-то вроде self.performSegue("back")....
но это кажется плохой идеей.
Как правильно это сделать?
16 ответов
Свифт 3:
Если вы хотите вернуться к предыдущему виду контроллера
_ = navigationController?.popViewController(animated: true)
Если вы хотите вернуться к корневому контроллеру представления
_ = navigationController?.popToRootViewController(animated: true)
Свифт 3, Свифт 4
if movetoroot {
navigationController?.popToRootViewController(animated: true)
} else {
navigationController?.popViewController(animated: true)
}
navigationController является необязательным, поскольку его может не быть.
Свифт 5 и выше
вариант 1: использование с контроллером навигации
self.navigationController?.popViewController(animated: true)
Случай 2: использование с настоящим контроллером представления
self.dismiss(animated: true, completion: nil)
Свифт 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)
}
Swift 4
Есть два способа вернуться / вернуться к предыдущему ViewController:
- Первый случай: если вы использовали:
self.navigationController?.pushViewController(yourViewController, animated: true)
в этом случае вам нужно использоватьself.navigationController?.popViewController(animated: true)
- Второй случай: если вы использовали:
self.present(yourViewController, animated: true, completion: nil)
в этом случае вам нужно использоватьself.dismiss(animated: true, completion: nil)
В первом случае убедитесь, что вы встроили свой ViewController в навигационный контроллер в вашей раскадровке
В случае, когда вы представили UIViewController
изнутри UIViewController
то есть..
// Main View Controller
self.present(otherViewController, animated: true)
Просто позвоните dismiss
функция:
// Other View Controller
self.dismiss(animated: true)
Если Segue имеет вид "Показать" или "Нажать", то Вы можете вызвать "popViewController(animated: Bool)" в экземпляре UINavigationController. Или, если segue является своего рода "настоящим", тогда вызовите "dismiss(animated: Bool, завершение: (() -> Void)?)" С экземпляром UIViewController
Для Swift 3 вам просто нужно написать следующую строку кода
_ = navigationController?.popViewController(animated: true)
Это работает для меня (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")
}
}
}
}
Попробуйте это: для предыдущего просмотра используйте это:
navigationController?.popViewController(animated: true)
поп в корень используйте этот код:
navigationController?.popToRootViewController(animated: true)
Хочу предложить другой подход к этой проблеме. Вместо использования контроллера навигации для отображения контроллера представления используйте переходы размотки. У этого решения есть несколько, но действительно важных преимуществ:
- Исходный контроллер может вернуться к любому другому конечному контроллеру (а не только к предыдущему), ничего не зная о месте назначения.
- Сегменты 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)
Я обнаружил, что этот подход очень окупается, когда ваша навигация начинает усложняться.
Я надеюсь, что это помогает кому-то.
Swift 4.0 Xcode 10.0 с TabViewController в качестве последнего представления
Если ваш последний ViewController встроен в TabViewController, приведенный ниже код отправит вас в корень...
navigationController?.popToRootViewController(animated: true)
navigationController?.popViewController(animated: true)
Но если вы действительно хотите вернуться к последнему представлению (это может быть представление Tab1, Tab2 или Tab3...), вы должны написать следующий код:
_ = self.navigationController?.popViewController(animated: true)
Это работает для меня, я использовал представление после одного из моего TabView:)
Для вопросов, касающихся того, как встроить ваш viewController в navigationController в раскадровке:
- Откройте раскадровку, на которой расположен ваш другой viewController
- Нажмите на viewController, с которого вы хотите запустить свой контроллер навигации
- В верхней части Xcode нажмите "Редактор"
- -> Нажмите встраивать в
- -> Нажмите "Контроллер навигации
Я сделал это вот так
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)
}
Если вы хотите закрыть предыдущие два контроллера представления, просто вызовите popViewController два раза следующим образом:
self.navigationController?.popViewController(animated: true)
self.navigationController?.popViewController(animated: true)
Я могу перенаправить на корневую страницу, написав код в "viewDidDisappear" контроллера,
override func viewDidDisappear(_ animated: Bool) {
self.navigationController?.popToRootViewController(animated: true)
}