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

调用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:30:21