假设segue导航是ViewController -> FirstViewController -> SecondViewController。从SecondViewController 到ViewController 有一个放松。您可以在中介FirstViewController 中添加以下代码来检测展开动作。
import UIKit
class FirstViewController: UIViewController {
var unwindAction:Bool = false
override func viewDidAppear(animated: Bool) {
if unwindAction {
println("Unwind action")
unwindAction = false
}
}
override func viewControllerForUnwindSegueAction(action: Selector, fromViewController: UIViewController, withSender sender: AnyObject?) -> UIViewController? {
self.unwindAction = true
return super.viewControllerForUnwindSegueAction(action, fromViewController: fromViewController, withSender: sender)
}
}
编辑
在考虑了这一点之后,我决定解决这个问题取决于您在这里处理的复杂性。当你做 unwind segue 的时候你到底在做什么?此处给出的解决方案是可行的并且有效——仅当您想检测它是否是展开操作时。如果您想在展开发生的点之间传递数据到根节点怎么办?如果您想在其中一个中间视图控制器中进行一系列复杂的准备工作怎么办?如果你想同时做这两个怎么办?
在如此复杂的场景中,我会立即排除覆盖视图控制器的展开方法。在那里做这样的操作会起作用,但它不会是干净的。一个方法将做它不应该做的事情。闻到了吗?那是代码味道。
如果某个视图控制器可以通过某种方式通知层次结构中的下一个视图控制器发生的事件怎么办?更好的是,我们如何在不将这两者紧密耦合的情况下做到这一点?
协议。
有一个类似的协议定义:
protocol UnwindResponding {
prepareForUnwindSegue(segue:UISegue , formViewController:UIViewController, withImportantInfo info:[String,AnyObject])
}
使用协议,您将保持对象之间的关系——在这种情况下是视图控制器的层次结构——显式。在特定事件发生时,您将调用委托给层次结构中的下一个控制器,通知另一个视图控制器中特定事件的发生。这是一个例子:
override func prepareForSegue(segue:UIStoryboardSegue, sender:AnyObject?) {
if let unwindResponder = self.presentingViewController as? UnwindResponding where segue.identifier = "unwindSegue" {
unwindResponder.prepareForUnwindSegue(segue:UISegue, fromViewController:self,info:info)
}
}
在中间视图控制器中,您可以执行以下操作:
extension IntermediaryViewController : UnwindResponding {
prepareForUnwindSegue(segue:UISegue , fromViewController:UIViewController, withImportantInfo info:[String,AnyObject]) {
if let unwindResponder = self.presentingViewController {
unwindResponder.prepareForUnwindSegue(segue,fromViewController:fromViewController, info:info)
}
unwindSegue = true
}
}
当然,如果您只是想检测 unwind segues,您不会想这样做。也许你会,你永远不知道未来会发生什么。保持代码清洁永远不会受到伤害。