Пропустить/добавить контроллер просмотра в стеке навигации
У меня есть три контроллера просмотра, встроенных в навигационный контроллер. Я хочу перейти от VC1 к VC3, чтобы в VC3 кнопка назад на навигационном элементе направила пользователя в VC2 вместо VC1. Я думаю, что это должно быть сделано путем добавления VC2 к стеку навигации между VC1 и VC3 при создании VC3 или пропуском второго контроллера просмотра.
Я пробовал это:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let identifier = segue.identifier {
switch identifier {
case "JumpToThirdVCSegue":
if let secondvc = segue.destinationViewController as? SecondViewController {
secondvc.performSegueWithIdentifier("ThirdVCSegue", sender: self)
}
default: break
}
}
}
но я не мог заставить его работать. Возможно, выполнение segue невозможно, если контроллер просмотра еще не открыт?
Каков наилучший способ пропустить контроллер просмотра/добавить контроллер просмотра в середине навигационного стека? Надеюсь, это поможет вам понять, что я пытаюсь сделать:
![]()
Ответы
Ответ 1
Что-то вроде этого должно работать:
self.navigationController?.pushViewController(viewController2, animated: true)
self.navigationController?.pushViewController(viewController3, animated: true)
EDIT:
Если вы хотите нажать второй контроллер просмотра, не будучи замеченным пользователем, вам нужно добавить его в контроллер навигации после нажатия третьего контроллера. Это можно сделать, выполнив UINavigationControllerDelegate
. Вы можете сохранить свой второй контроллер представления в переменной и вставить его в иерархию контроллеров навигации в методе делегата. Ваш главный контроллер будет выглядеть следующим образом:
class MyViewController: UIViewController, UINavigationControllerDelegate {
var viewControllerToInsertBelow : UIViewController?
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.delegate = self
}
func pushTwoViewControllers() {
if let viewController2 = self.storyboard?.instantiateViewControllerWithIdentifier("id1"),
let viewController3 = self.storyboard?.instantiateViewControllerWithIdentifier("id2") { //change this to your identifiers
self.viewControllerToInsertBelow = viewController2
self.navigationController?.pushViewController(viewController3, animated: true)
}
}
//MARK: - UINavigationControllerDelegate
func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
if let vc = viewControllerToInsertBelow {
viewControllerToInsertBelow = nil
let index = navigationController.viewControllers.indexOf(viewController)!
navigationController.viewControllers.insert(vc, atIndex: index)
}
}
}
Ответ 2
Изменить: с помощью быстрых и segues это должно работать:
override func performSegueWithIdentifier(identifier: String?, sender: AnyObject?) {
super.performSegueWithIdentifier(identifier, sender: sender);
if identifier == "JumpToThirdVCSegue" {
// now the vc3 was already pushed on the navigationStack
var navStackArray : [AnyObject]! = self.navigationController!.viewControllers
// insert vc2 at second last position
navStackArray.insert(viewController2, atIndex: navStackArray.count - 2)
// update navigationController viewControllers
self.navigationController!.setViewControllers(navStackArray, animated:false)
}
}
Таким образом, вы переопределяете performSegueWithIdentifier в VC1, чтобы изменить стек навигации, когда segue для VC3 фактически был выполнен (и не только подготовлен).
Это предполагает, что вы хотите обрабатывать эту специальную навигационную логику в VC1.
Ответ 3
Мое решение состояло бы в том, чтобы сохранить свойство BOOL, когда вы должны перейти к третьему, а когда не пропустить, например, объявить shouldSkip в VC2, чтобы, если вы установили его в готовом segue, как показано ниже, вы можете действовать в соответствии с тем, что в VC2
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let identifier = segue.identifier {
switch identifier {
case "JumpToThirdVCSegue":
secondvc.shouldSkip=true
}
default: break
}
}
}
а затем в viewDidload VC2 вы должны проверить этот BOOL, и если это правда и выполнить segue, и если не просто перейти
вы также можете передавать пропуск, когда этот вид пропуска не требуется
Ответ 4
Существует метод (ссылка), который решает проблему пропуска UIViewController
.
Просто передайте ему все необходимые UIViewControllers
(в навигационном порядке), а последний будет выполнен как текущий активный UIViewController
(если он уже не является активным).