Пропустить / добавить контроллер вида в стек навигации
У меня есть три контроллера вида, встроенные в навигационный контроллер. Я хочу перейти от 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 невозможно, когда контроллер представления еще не открыт?
каков наилучший способ пропустить контроллер вида / добавить контроллер вида в середине стека навигации? Я надеюсь, это поможет вам понять, что я пытаюсь сделать:
5 ответов
что-то вроде этого должно работать:
self.navigationController?.pushViewController(viewController2, animated: true)
self.navigationController?.pushViewController(viewController3, animated: true)
EDIT:
Если вы хотите нажать второй контроллер вида, не будучи замеченным пользователем, вам нужно добавить его в навигационный контроллер после нажатия третьего контроллера вида. Это можно сделать путем реализации UINavigationControllerDelegate
. Второй контроллер представления можно сохранить в переменной и вставить в иерархию навигационных контроллеров в методе delegate. Ваш главный контроллер вида будет выглядеть так следующий:
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)
}
}
}
Edit: используя swift и 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, чтобы изменить стек навигации, когда сегмент к VC3 фактически был выполнен (и не только в подготовке). Это предполагает, что вы хотите обработать эту специальную логику навигации в VC1.
вы можете использовать метод
func setViewControllers(_ viewControllers: [UIViewController],
animated: Bool)
вот документацию (ссылке), что решает UIViewController
проблема вприпрыжку.
Просто передайте все необходимое UIViewControllers
ему (в навигационном порядке) и последний будет сделан как текущий активный UIViewController
(если он уже не является активным).
if var navstack = navigationController?.viewControllers{
navstack.append(contentsOf: [vc1,vc2])
navigationController?.setViewControllers(navstack, animated: true)
}
работает
моим решением было бы сохранить свойство BOOL, когда вы должны перейти к третьему, а когда не пропустить, например, объявление " shouldSkip’ в VC2, чтобы, если вы установите его в prepare 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, а если не просто двигаться дальше вы также можете пройти проход, когда такой пропуск не нужен