从‘Over Current Context’视图控制器返回时如何触发指定代码?
解决Over Current Context模态返回时触发指定代码的问题
这个问题我之前也碰到过,其实根源在于Over Current Context的展示特性——这种方式下,原来的ViewController的视图根本没被隐藏,所以系统不会触发viewWillAppear方法。下面给你几个实用的解决办法,选哪个看你的场景:
方法一:闭包回调(简单直接,适合轻量场景)
这种方式代码量最少,适合只需要简单传递回调的情况:
- 先在
ViewController2里定义一个闭包属性:
class ViewController2: UIViewController { // 定义可选闭包,用于返回时的回调 var onDismiss: (() -> Void)? @IBAction func close(_ sender: Any) { self.dismiss(animated: true) { // 在dismiss动画完成后调用闭包 self.onDismiss?() } } }
- 在
ViewController跳转前设置闭包内容:
class ViewController: UIViewController { override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vc2 = segue.destination as? ViewController2 { // 给闭包赋值,写你要触发的代码 vc2.onDismiss = { print("回到ViewController了,执行指定操作") // 比如刷新数据、更新UI之类的逻辑都可以放这里 } } } // 原有的viewWillAppear代码(注意你之前写错了,应该调用super.viewWillAppear而不是super.viewDidAppear) override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) print("will appear") } }
方法二:代理模式(结构清晰,适合复杂交互)
如果后续可能需要扩展更多回调逻辑,代理模式会更规范:
- 先定义一个代理协议:
// 定义代理协议,方法用于通知ViewController返回事件 protocol ViewController2Delegate: AnyObject { func viewController2DidFinishDismiss() }
- 在
ViewController2里添加代理属性:
class ViewController2: UIViewController { // 用weak避免循环引用 weak var delegate: ViewController2Delegate? @IBAction func close(_ sender: Any) { self.dismiss(animated: true) { // 通知代理执行回调 self.delegate?.viewController2DidFinishDismiss() } } }
- 让
ViewController遵守协议并设置代理:
class ViewController: UIViewController, ViewController2Delegate { override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vc2 = segue.destination as? ViewController2 { vc2.delegate = self } } // 实现代理方法,写要触发的代码 func viewController2DidFinishDismiss() { print("通过代理触发回调,执行操作") } }
方法三:通知中心(适合跨页面的全局回调)
如果你的回调需要通知多个页面,或者不想直接耦合两个ViewController,可以用通知:
- 在
ViewController里注册并监听通知:
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 注册通知,监听ViewController2的返回事件 NotificationCenter.default.addObserver( self, selector: #selector(handleVC2Dismiss), name: NSNotification.Name("ViewController2Dismissed"), object: nil ) } @objc func handleVC2Dismiss() { // 这里写要触发的代码 print("收到通知,执行指定操作") } // 记得在页面销毁时移除通知,避免内存泄漏 deinit { NotificationCenter.default.removeObserver(self) } }
- 在
ViewController2的返回方法里发送通知:
class ViewController2: UIViewController { @IBAction func close(_ sender: Any) { self.dismiss(animated: true) { // 发送通知 NotificationCenter.default.post( name: NSNotification.Name("ViewController2Dismissed"), object: nil ) } } }
内容的提问来源于stack exchange,提问作者CL So
相关产品推荐
相关产品推荐

