iOS/Swift中如何用Unwind Segue从E返回指定ViewController(C/B/D)
搞定Unwind Segue:从E一键回到C/B/D的方案
嘿,我明白你的需求了——E页面只有一个返回按钮,但要根据不同的跳转路径(比如从C→A→E来的就回C,从C→B→BB→E来的就回B),这确实不能用普通的固定unwind segue,得搞点动态逻辑。下面给你两种靠谱的方案,选适合你的来用:
方案一:动态触发对应Unwind Segue(推荐需要处理返回逻辑的场景)
这种方式会利用系统的unwind机制,还能在目标页面(C/B/D)里写返回后的处理逻辑,步骤如下:
1. 在目标VC中添加专属Unwind方法
分别在CViewController、BViewController、DViewController里添加各自的unwind方法,名字要区分开,方便后续识别:
// CViewController.swift @IBAction func unwindToC(_ sender: UIStoryboardSegue) { // 这里可以加回到C后的逻辑,比如刷新列表、重置状态 print("回到C页面啦") } // BViewController.swift @IBAction func unwindToB(_ sender: UIStoryboardSegue) { print("回到B页面啦") } // DViewController.swift @IBAction func unwindToD(_ sender: UIStoryboardSegue) { print("回到D页面啦") }
2. 在Storyboard中创建Unwind Segue并设置ID
打开你的Storyboard,选中E页面:
- 按住
Ctrl,从E页面的空白处(或者顶部的ViewController图标)拖到页面顶部的Exit图标(那个绿色的箭头) - 松开后会弹出你刚才写的三个unwind方法,先选
unwindToC:,这就创建了一个unwind segue - 选中这个segue,在右侧Attributes Inspector里把Identifier设为
UnwindToC - 重复上面的操作,分别创建对应
unwindToB:和unwindToD:的segue,ID分别设为UnwindToB、UnwindToD
3. 在E页面的返回按钮中动态判断并触发
给E页面的返回按钮添加点击事件,遍历当前导航栈,找到最近的C/B/D,然后触发对应的segue:
// EViewController.swift @IBAction func backButtonTapped(_ sender: UIButton) { guard let navStack = navigationController?.viewControllers else { // 没导航栈就默认返回上一页 navigationController?.popViewController(animated: true) return } // 从后往前遍历导航栈,找到第一个匹配的目标VC for vc in navStack.reversed() { switch vc { case is CViewController: performSegue(withIdentifier: "UnwindToC", sender: self) return case is BViewController: performSegue(withIdentifier: "UnwindToB", sender: self) return case is DViewController: performSegue(withIdentifier: "UnwindToD", sender: self) return default: continue } } // 兜底:如果没找到(理论上不会出现),就返回上一页 navigationController?.popViewController(animated: true) }
方案二:直接修改导航栈(简洁高效,适合仅跳转的场景)
如果你不需要在返回时触发特定的unwind逻辑,直接修改导航栈的方式更简单,不用管Storyboard的segue设置:
// EViewController.swift @IBAction func backButtonTapped(_ sender: UIButton) { guard let navStack = navigationController?.viewControllers else { navigationController?.popViewController(animated: true) return } // 遍历找到第一个C/B/D的位置,直接重置导航栈 for (index, vc) in navStack.enumerated() { if vc is CViewController || vc is BViewController || vc is DViewController { navigationController?.setViewControllers(Array(navStack[0...index]), animated: true) return } } navigationController?.popViewController(animated: true) }
这种方式会直接把导航栈截断到目标VC,效果和unwind是一样的,但代码更短,不需要额外配置Storyboard。
小提示
- 两种方案都能自动适配所有你的跳转路径,比如从
F→X→E来的话,遍历会找不到C/B/D,这时候兜底逻辑会返回X;如果需要从F→X→E回到F,只要把F也加入判断条件就行。 - 用unwind segue的话,还可以在
prepare(for:sender:)里给目标VC传递数据,比如把E页面的用户输入传回C/B/D。
内容的提问来源于stack exchange,提问作者K.L
相关产品推荐
相关产品推荐

