在导航堆栈中跳过/添加视图控制器

我有三个视图控制器embedded导航控制器。 我想从VC1到VC3,以便在VC3中导航项的后退button将引导用户到VC2而不是VC1。 我认为这应该通过创buildVC3将VC2添加到VC1和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是不可能的?

跳过视图控制器/在导航堆栈中添加视图控制器的最佳方法是什么? 我希望这可以帮助你理解我想要做的事情:

像这样的东西应该工作:

  self.navigationController?.pushViewController(viewController2, animated: true) self.navigationController?.pushViewController(viewController3, animated: true) 

编辑:

如果你想推第二个视图控制器而不被用户注意到,你需要在第三个视图控制器被按下后把它添加到导航控制器。 这可以通过实现UINavigationControllerDelegate来完成。 您可以将第二个视图控制器存储在一个variables中,并将其插入到委托方法中的导航控制器层次结构中。 您的主视图控制器将如下所示:

 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) } } } 

编辑:使用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) } } 

所以你重写VC1中的performSegueWithIdentifier来改变导航堆栈的时候,实际上已经执行了VC3(并且不仅在准备中)。 假设你想在VC1中处理这个特殊的导航逻辑。

我的解决scheme是保持一个布尔属性,当你应该跳到第三,当不跳过,就像在VC2中声明'shouldSkip',以便如果你在准备像下面那样设置它,你可以根据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,如果不是只是继续前进,你也可以通过pass,只要这种跳过是不必要的

存在解决UIViewController跳过问题的方法( 链接 )。 只需将所有需要的UIViewControllers传递给它(按照导航顺序),最后一个将作为当前活动的UIViewController (如果它已经不是活动的)。