You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编程关闭模态VC时,如何通知父VC刷新TableView?

模态视图编辑完成后刷新原控制器TableView的方案

针对你提出的需求——VC2通过编程方式关闭时通知VC1刷新TableView,而滑动关闭不触发操作,下面提供两种最常用的实现方式:

一、闭包(完成处理程序)实现

这是最直接的方式,契合你提到的“完成处理程序”思路:

1. 在VC2中定义闭包属性

在VC2里添加一个可选闭包,用来传递编辑完成的信号:

// VC2.swift
class VC2: UIViewController {
    // 定义闭包,用于通知VC1刷新数据
    var onEditCompleted: (() -> Void)?
    
    // 点击"返回/保存"按钮的方法
    @IBAction func confirmAndDismiss(_ sender: UIButton) {
        // 先执行编辑数据的保存逻辑
        saveEditedContent()
        
        // 调用闭包,通知VC1执行刷新
        onEditCompleted?()
        
        // 关闭模态视图
        dismiss(animated: true, completion: nil)
    }
    
    private func saveEditedContent() {
        // 这里编写你的数据保存代码,比如更新数据源模型
    }
}

2. 在VC1中present VC2时绑定闭包

在VC1的TableView选中事件里,初始化VC2并设置闭包内容:

// VC1.swift
class VC1: UIViewController, UITableViewDataSource {
    @IBOutlet weak var tableView: UITableView!
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // 初始化VC2(假设通过Storyboard创建)
        guard let vc2 = storyboard?.instantiateViewController(withIdentifier: "VC2") as? VC2 else { return }
        
        // 绑定闭包,弱引用self避免循环引用
        vc2.onEditCompleted = { [weak self] in
            self?.tableView.reloadData()
        }
        
        // 模态弹出VC2
        present(vc2, animated: true, completion: nil)
    }
    
    // 其他TableView数据源方法...
}

说明:滑动关闭VC2是系统默认的dismiss行为,不会触发我们自定义的confirmAndDismiss方法,因此闭包不会被调用,自然不会执行刷新,正好符合你“滑动关闭相当于取消”的需求。

二、代理模式实现

如果需要更清晰的接口定义,或者后续可能扩展多个回调事件,推荐使用代理模式:

1. 在VC2中定义代理协议

// VC2.swift
protocol VC2EditDelegate: AnyObject {
    func vc2DidFinishEditing()
}

class VC2: UIViewController {
    // 代理对象,用weak避免循环引用
    weak var delegate: VC2EditDelegate?
    
    @IBAction func confirmAndDismiss(_ sender: UIButton) {
        saveEditedContent()
        // 通知代理执行刷新
        delegate?.vc2DidFinishEditing()
        dismiss(animated: true, completion: nil)
    }
    
    private func saveEditedContent() {
        // 数据保存逻辑
    }
}

2. 在VC1中遵守并实现代理协议

// VC1.swift
class VC1: UIViewController, UITableViewDataSource, VC2EditDelegate {
    @IBOutlet weak var tableView: UITableView!
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        guard let vc2 = storyboard?.instantiateViewController(withIdentifier: "VC2") as? VC2 else { return }
        vc2.delegate = self
        present(vc2, animated: true, completion: nil)
    }
    
    // 实现代理方法
    func vc2DidFinishEditing() {
        tableView.reloadData()
    }
}

注意事项

  • 无论是闭包还是代理,都要使用weak self避免循环引用,防止内存泄漏。
  • 不推荐使用NotificationCenter:这种全局通知方式会增加代码耦合度,对于两个直接关联的控制器来说,闭包或代理是更合适的选择。

内容的提问来源于stack exchange,提问作者Jim Burke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:45:33