在最近刚刚完成的一个项目中,我们碰到了一种对页面跳转较复杂的情况:
我们高度复用了同一个复杂的页面,根据页面内各个状态的不同,有一个统一的跳转按钮处理。这个页面可能在不同的navi层级中,而且跳转到的页面也会超出navi的范围。要是使用常规的pop和dismiss方法,需要手动加特别多的判断。
考虑到项目的实际情况(主要使用IB来配置界面),我们最后决定使用unwind segue来解决这个问题。
unwind segue能够从performSegue的那个页面开始,按照 navigation hierarchy 逐级往上查找能够处理这个 segue 的 vc,找到以后则可以直接跳到相应的 vc 并进行数据传递等工作。因为有 segue 在,可以方便的取到 sourceVC 和 destinationVC,于是传递数据也十分方便。并且 unwind segue 不需要指定destinationVC,本身就是松耦合的。
配置 unwind segue 也十分简单。
首先,在 segue 的 destinationVC(即你想要 segue 到的 VC )中添加一个 IBAction 方法,并且可以接受一个 UIStoryboardSegue 作为参数。
@IBAction func doSomething(segue: UIStoryboardSegue) {
//handle the segue
}
然后在 segue 的 sourceVC 所在的 storyboard 里进行连线。
官方把这个方法称为 unwind Action ,并对调用时间在 perform segue 之前。
This unwind action is invoked just before the unwind segue is performed. You can access the
sourceViewController
of theUIStoryboardSegue
parameter to retrieve any data from the view controller that initiated the unwind segue.
注意: 需要点击storyboard上的Exit才会显示右边的segue。
在document outline中点击刚刚设置的segue,之后在IB中设置segue的identifier。
然后在发出这个segue的VC中连接button进行segue,或手动调用performSegue方法,或进行更多设置:
@IBAction func push() {
performSegueWithIdentifier("doSomething", sender: self)
}
//if needed
override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {
//do some check
return true
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//do some configure
}
unwind segue 会逐级往上查找可以处理该 segue 的 VC,只要 destinationVC 在 navigation hierarchy 中,即可跳转过去。
总结一下,你需要做的有:
- 一个 IBAction 方法,带一个 segue 参数
- 在 sourceVC 中配置 segue
- 手动调用 performSegue 或者直接连线
无论你的 sourceVC 在 navigation hierarchy 中的哪个位置,只要它的 destinationVC 在 navigation hierarchy 中且实现了那个 IBAction 方法,即可方便的跳转过去。由于 segue 可以取得 sourceVC,所以传递数据也非常方便。
它集合了 protocol 的好处,也可以轻松的进行跳转。
不过,它只能在IB中使用,所以。。
以下是官方文档对 unwind 过程的一个描述:
- The unwind segue traverses your navigation hierarchy to locate the destination view controller. This step is described in detail under How an Unwind Segue Determines its Destination View Controller.
- The view controller that initiated the unwind segue is sent a
prepareForSegue:sender:
message. The default implementation does nothing. Your view controller can override this method to pass data to the destination view controller. - The destination view controller's unwind action is invoked.
- The unwind segue animates the visual transition between the source and destination view controller.
参考文献:
- WWDC15 What's New in Storyboards
https://developer.apple.com/videos/play/wwdc2015/215/ - Technical Note TN2298 Using Unwind Segues
https://developer.apple.com/library/ios/technotes/tn2298/_index.html