以编程方式定义新的导航控制器订单/堆栈?

我有一个NavigationController ,嵌入了以下VC:VC1 – > VC2 – > VC3 – > VC4 – > VC5。 我的问题是,当我从VC5中删除时(编辑完成后),我发送回VC3,但我想以编程方式将VC4和VC5从堆栈中删除,即当用户被送回VC3时,我想要“返回” “在navagitionBar中带你去VC2(而不是你真正来自的VC5)。

这在IOS中出现了很多,你想要编辑模型,然后将它们发送回tableView / Collection视图,但是由于编辑已完成,你不再需要在导航堆栈中编辑viewControllers,因为它太混乱了UX。

在下面的屏幕截图中,右上角的VC是VC5: 在此处输入图像描述 通过self.performSegueWithIdentifier("backToPins", sender: self)将其返回到PinViewController(VC3 self.performSegueWithIdentifier("backToPins", sender: self)

我怎样才能做到这一点?

不要使用segue回来(pop)。

你应该使用popToViewController并传递特定的viewcontroller作为参数来弹出那个viewcontroller。

例如,如果您想要使用五个中的第三个视图控制器,那么您可以执行以下操作。 你可以只从viewcontroller数组更改索引到不同的视图控制器。

 let viewControllers: [UIViewController] = self.navigationController!.viewControllers as [UIViewController]; self.navigationController!.popToViewController(viewControllers[viewControllers.count - 3], animated: true); 

如果您正在使用segue,则意味着您将新的viewcontroller添加(推送)到导航堆栈。 在您的示例中,到达第5个视图后的堆栈就像,

VC1 - VC2 - VC3 - VC4 - VC5 (top of stack)

现在,如果你执行回到VC3,那么堆栈应该是这样的,

VC1 - VC2 - VC3 - VC4 - VC5 - VC3(top of stack)

如果你弹出到VC3然后你的堆栈就像,

VC1 - VC2 - VC3 (top of stack)

所以流行的viewcintrollers回去不要使用segue

希望这会有所帮助:)

最好的方法是通过放松segue。

VC3您可以定义适当的展开function:

 @IBAction func unwind(segue:UIStoryboardSegue) { if let sourceViewController = segue.sourceViewController as? VC5 { let myNewData=sourceViewController.someProperty self.someFunctionThatUpdatesScene() } 

然后在VC5场景中,您可以通过两种方式之一创建展开segue。

如果希望直接从对象(例如UIButton)触发它,则从检查器中的action拖动到场景顶部的exit图标,然后从弹出窗口中选择unwind

如果要以编程方式触发展开,则从左侧的资源管理器中的视图控制器对象拖动到退出图标,然后从弹出窗口中选择unwind 。 您现在将在资源管理器中看到一个展开的segue,您可以为它提供一个与任何segue一样的标识符。 您可以将此标识符与performSegueWithIdentifier

这种方法的优点是您不需要对UINavigationController堆栈的深度做任何假设,也不需要实现委托/协议来传回数据。

Apple有一个关于使用Unwind Segues的非常好的技术说明