Ios 以编程方式定义新的导航控制器顺序/堆栈?

Ios 以编程方式定义新的导航控制器顺序/堆栈?,ios,swift,uinavigationcontroller,Ios,Swift,Uinavigationcontroller,我有一个NavigationController,其中嵌入了以下VC:VC1->VC2->VC3->VC4->VC5。我的问题是,当我从VC5分离时(编辑完成后),我会将您送回VC3,但我希望以编程方式将VC4和VC5从堆栈中丢弃,也就是说,当用户被送回VC3时,我希望在navagitionBar中的“back”将您带回VC2(而不是您真正来自的VC5) 这在IOS中经常出现,您希望编辑模型,然后将它们发送回tableView/Collection视图,但由于编辑已完成,您不再希望在导航堆栈中编

我有一个
NavigationController
,其中嵌入了以下VC:VC1->VC2->VC3->VC4->VC5。我的问题是,当我从VC5分离时(编辑完成后),我会将您送回VC3,但我希望以编程方式将VC4和VC5从堆栈中丢弃,也就是说,当用户被送回VC3时,我希望在
navagitionBar
中的“back”将您带回VC2(而不是您真正来自的VC5)

这在IOS中经常出现,您希望编辑模型,然后将它们发送回tableView/Collection视图,但由于编辑已完成,您不再希望在导航堆栈中编辑ViewController,因为它太容易混淆UX

在下面的屏幕截图中,右上角的VC是VC5:它通过
self.performsguewithidentifier(“backToPins”,sender:self)


我该怎么做

不要使用
segue
返回(pop)

您应该使用
popToViewController
并将特定的
viewcontroller
作为参数传递给pop该viewcontroller

例如,如果您想在五个视图控制器中选择第三个,则可以执行以下操作。您只需将索引从viewcontroller数组更改为其他视图控制器即可

let viewControllers: [UIViewController] = self.navigationController!.viewControllers as [UIViewController];
self.navigationController!.popToViewController(viewControllers[viewControllers.count - 3], animated: true);
如果您使用的是segue,这意味着您将向导航堆栈添加(推送)新的viewcontroller。在您的示例中,到达第五视图后的堆栈如下:

VC1-VC2-VC3-VC4-VC5(栈顶)

现在,如果您执行了返回VC3的检查,那么堆栈应该是这样的

VC1-VC2-VC3-VC4-VC5-VC3(栈顶)

如果你跳到VC3,你的堆栈就像

VC1-VC2-VC3(堆栈顶部)

因此,要返回的pop viewcontroller不使用
segue


希望这会有所帮助:)

不要使用
segue
来返回(pop)

您应该使用
popToViewController
并将特定的
viewcontroller
作为参数传递给pop该viewcontroller

例如,如果您想在五个视图控制器中选择第三个,则可以执行以下操作。您只需将索引从viewcontroller数组更改为其他视图控制器即可

let viewControllers: [UIViewController] = self.navigationController!.viewControllers as [UIViewController];
self.navigationController!.popToViewController(viewControllers[viewControllers.count - 3], animated: true);
如果您使用的是segue,这意味着您将向导航堆栈添加(推送)新的viewcontroller。在您的示例中,到达第五视图后的堆栈如下:

VC1-VC2-VC3-VC4-VC5(栈顶)

现在,如果您执行了返回VC3的检查,那么堆栈应该是这样的

VC1-VC2-VC3-VC4-VC5-VC3(栈顶)

如果你跳到VC3,你的堆栈就像

VC1-VC2-VC3(堆栈顶部)

因此,要返回的pop viewcontroller不使用
segue


希望这会有所帮助:)

最好的方法是通过放松阶段

VC3
中,您可以定义一个适当的展开功能:

@IBAction func unwind(segue:UIStoryboardSegue) {
    if let sourceViewController = segue.sourceViewController as? VC5 {
         let myNewData=sourceViewController.someProperty
         self.someFunctionThatUpdatesScene()
}
然后在VC5场景中,您可以通过以下两种方式之一创建一个展开序列

如果希望直接从对象(如UIButton)触发,请从检查器中的
操作
拖动到场景顶部的
退出
图标,然后从弹出窗口中选择
展开

如果要以编程方式触发展开,请从左侧资源管理器中的视图控制器对象拖动到退出图标,然后从弹出窗口中选择
展开
。现在,您将在浏览器中看到一个展开序列,您可以像对待任何序列一样给它一个标识符。您可以将此标识符与
performsguewithidentifier

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


苹果有一个非常好的技术说明

做到这一点的最好方法是通过一个放松序列

VC3
中,您可以定义一个适当的展开功能:

@IBAction func unwind(segue:UIStoryboardSegue) {
    if let sourceViewController = segue.sourceViewController as? VC5 {
         let myNewData=sourceViewController.someProperty
         self.someFunctionThatUpdatesScene()
}
然后在VC5场景中,您可以通过以下两种方式之一创建一个展开序列

如果希望直接从对象(如UIButton)触发,请从检查器中的
操作
拖动到场景顶部的
退出
图标,然后从弹出窗口中选择
展开

如果要以编程方式触发展开,请从左侧资源管理器中的视图控制器对象拖动到退出图标,然后从弹出窗口中选择
展开
。现在,您将在浏览器中看到一个展开序列,您可以像对待任何序列一样给它一个标识符。您可以将此标识符与
performsguewithidentifier

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


苹果公司有一个非常好的技术说明,你只需使用一个放松序列。在VC3中定义展开方法,并为YouTunks@Paulw11 unwindForSegue管理魔术将使我进入VC3,但我需要使用添加在VC5中的新模型数据“刷新”VC3,因此我不确定在这里展开到以前的VC3实例是否最好,我想我需要一个具有更新模型数据的新实例?您可以通过一个展开段将数据传递回;
unwind
方法接收一个
UIstoryboardSegue
,它有一个
sourceViewController
,您可以像
prepareFoeSegue
中的
destinationViewController
一样使用它,您只需使用一个unwind segue即可。在VC3中定义展开方法,然后为YouTunks@Paulw11 unwindForSegue管理魔术将使我进入VC3,但我需要使用添加在VC5中的新模型数据“刷新”VC3,因此我不确定在这里展开到以前的VC3实例是否最好,我想我需要一个