Rewind segue未触发viewDidAppear问题求助
兄弟我太懂你这个坑了!之前做项目的时候也踩过一模一样的雷,咱们来拆解下问题到底出在哪,以及怎么解决:
问题根源分析
核心原因就出在Modal Segue和Push Segue的生命周期差异上:
- 当你从VC1用Modal方式跳转到VC2时,VC1的View并没有被销毁,只是被VC2的View完全覆盖了。当你通过Rewind Segue从VC2返回VC1时,系统只是把VC2 dismiss掉,VC1的View本来就处于「已加载但被覆盖」的状态,并没有经历「从不可见切换到可见」的过程,所以
viewDidAppear(_:)方法不会被触发。 - 而你提到的第三个VC返回时
viewDidAppear正常工作,大概率是因为第三个VC是通过Push Segue(导航栈跳转)进入的——这种情况下VC1的View会被压入导航栈底,当你从VC3返回时,VC1的View会重新回到屏幕上,自然会触发viewDidAppear(_:)。
可行的解决方案
针对这个问题,有几种简单直接的解决方式,选你顺手的用就行:
1. 把更新逻辑抽成独立方法,在Rewind时直接调用
把VC1里更新标签的逻辑从viewDidAppear里抽出来,做成一个单独的方法,然后在VC2的Rewind Segue准备阶段直接调用这个方法:
// 在VC1里定义更新方法 func updateLabelWithGlobalVar() { yourLabel.text = "\(globalVariable)" } // 在VC2的Rewind Segue方法里调用 @IBAction func unwindToVC1(segue: UIStoryboardSegue) { if let vc1 = segue.source.presentingViewController as? ViewController1 { vc1.updateLabelWithGlobalVar() } }
2. 用通知中心监听VC2的dismiss事件
在VC1里监听VC2被 dismiss 的通知,收到通知后立即更新标签:
// VC1的viewDidLoad里添加监听 override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(updateLabel), name: NSNotification.Name("VC2Dismissed"), object: nil) } // VC1里的更新方法 @objc private func updateLabel() { yourLabel.text = "\(globalVariable)" } // VC2的Rewind按钮点击时发送通知 @IBAction func rewindBtnTapped(_ sender: UIButton) { // 先更新全局变量 globalVariable = newValue // 发送通知 NotificationCenter.default.post(name: NSNotification.Name("VC2Dismissed"), object: nil) // 执行Rewind Segue performSegue(withIdentifier: "unwindToVC1", sender: self) } // 别忘了在VC1的deinit里移除监听,避免内存泄漏 deinit { NotificationCenter.default.removeObserver(self) }
3. 用闭包回调传递更新事件
在VC2里定义一个闭包属性,当准备返回时调用闭包通知VC1更新:
// VC2里定义闭包 class ViewController2: UIViewController { var onUpdate: (() -> Void)? @IBAction func rewindBtnTapped(_ sender: UIButton) { // 更新全局变量 globalVariable = newValue // 调用闭包通知VC1 onUpdate?() // 执行Rewind Segue performSegue(withIdentifier: "unwindToVC1", sender: self) } } // VC1跳转VC2时设置闭包 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vc2 = segue.destination as? ViewController2 { vc2.onUpdate = { [weak self] in self?.updateLabelWithGlobalVar() } } }
这里用weak self是为了避免循环引用,防止内存泄漏。
内容的提问来源于stack exchange,提问作者callum schenk
相关产品推荐
相关产品推荐

