调用dismissViewControllerAnimated后,如何刷新含UITableView的ViewController并显示新单元格?
嘿,这个场景我太熟悉了!问题出在你从「Create Cell」页面 dismiss 回来后,原 ViewController 根本不知道你新增了数据,自然不会刷新 TableView。下面给你几种最常用且恰当的解决办法,按推荐程度排序:
1. 闭包(Closure):最简洁直接的方案
这种方式代码量少、逻辑清晰,特别适合这种简单的反向通知场景。
步骤1:在「Create Cell」ViewController 里定义闭包属性
class CreateCellViewController: UIViewController { // 定义一个闭包,用来通知原页面刷新 var onCellCreated: (() -> Void)? // 假设这是你创建新单元格的按钮点击方法 @IBAction func saveNewCell(_ sender: UIButton) { // 1. 先完成新单元格数据的保存(比如添加到数据源数组/数据库) saveNewCellData() // 2. 触发闭包,通知原页面刷新 onCellCreated?() // 3. 关闭当前页面 dismiss(animated: true) } }
步骤2:在原 ViewController 跳转时绑定闭包
class YourTableViewController: UIViewController { @IBOutlet weak var tableView: UITableView! var cellDataSource: [YourCellModel] = [] // 跳转到Create页面的方法 @IBAction func goToCreateCell(_ sender: UIBarButtonItem) { let createVC = storyboard?.instantiateViewController(withIdentifier: "CreateCellVC") as! CreateCellViewController // 绑定闭包,这里用weak self避免循环引用 createVC.onCellCreated = { [weak self] in // 1. 更新数据源(比如重新从数据库拉取最新数据,或者直接添加刚才创建的模型) self?.cellDataSource = self?.fetchLatestCellData() ?? [] // 2. 刷新TableView self?.tableView.reloadData() } // 模态弹出Create页面,这样不会影响底部的标签栏 present(createVC, animated: true) } }
2. 通知中心(NotificationCenter):适合跨多页面的场景
如果你的项目里有多个页面需要监听「新增单元格」的事件,用通知会更方便,但记得要及时移除观察者避免内存泄漏。
步骤1:在原 ViewController 注册通知
class YourTableViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 注册通知,监听单元格创建完成的事件 NotificationCenter.default.addObserver(self, selector: #selector(refreshTableView), name: NSNotification.Name("CellCreatedNotification"), object: nil) } @objc private func refreshTableView() { // 更新数据源并刷新表格 cellDataSource = fetchLatestCellData() tableView.reloadData() } // 记得在页面销毁时移除观察者 deinit { NotificationCenter.default.removeObserver(self) } }
步骤2:在「Create Cell」页面发送通知
class CreateCellViewController: UIViewController { @IBAction func saveNewCell(_ sender: UIButton) { saveNewCellData() // 发送通知 NotificationCenter.default.post(name: NSNotification.Name("CellCreatedNotification"), object: nil) dismiss(animated: true) } }
3. 代理(Delegate):适合复杂交互场景
如果「Create Cell」页面需要给原页面传递更多数据(比如新创建的单元格模型),代理模式会更规范。
步骤1:定义代理协议
// 定义协议,注意用AnyObject确保只能被类遵守 protocol CreateCellDelegate: AnyObject { func didCreateNewCell(with model: YourCellModel) }
步骤2:在「Create Cell」页面设置代理属性
class CreateCellViewController: UIViewController { weak var delegate: CreateCellDelegate? @IBAction func saveNewCell(_ sender: UIButton) { let newCellModel = createNewCellModel() saveNewCellData(model: newCellModel) // 调用代理方法,传递新模型 delegate?.didCreateNewCell(with: newCellModel) dismiss(animated: true) } }
步骤3:原 ViewController 遵守并实现代理
class YourTableViewController: UIViewController, CreateCellDelegate { func goToCreateCell() { let createVC = storyboard?.instantiateViewController(withIdentifier: "CreateCellVC") as! CreateCellViewController createVC.delegate = self present(createVC, animated: true) } // 实现代理方法 func didCreateNewCell(with model: YourCellModel) { // 直接把新模型添加到数据源,不用重新拉取 cellDataSource.append(model) // 可以选择只刷新新增的行,比reloadData更高效 tableView.insertRows(at: [IndexPath(row: cellDataSource.count-1, section: 0)], with: .automatic) } }
小提醒
不管用哪种方法,都要确保在刷新 TableView 之前,数据源已经完成更新(比如数据已经成功保存到数据库/数组),不然刷新了也看不到新内容。
内容的提问来源于stack exchange,提问作者user9401139
相关产品推荐
相关产品推荐

