编程关闭模态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
相关产品推荐
相关产品推荐

