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

点击导航栏返回按钮时如何更新TableView数据源?

兄弟,我懂你这种场景下的困惑!之前我也在类似的发票管理APP里踩过坑,给你整理几个亲测有效的方案,应该能帮你解决问题:

方案1:用Unwind Segue(最贴合你提到的场景)

你之前可能没摸透Unwind Segue的正确用法,它不是普通的跳转segue,而是专门用来从子VC回退到父VC时触发回调的。按这几步来:

  1. 在第一个VC(发票列表VC)里定义Unwind方法:
    这个方法会在你从第三个VC回退回来时被调用,直接在这里更新数据源就行:
    @IBAction func unwindToInvoiceList(_ segue: UIStoryboardSegue) {
        // 先判断来源是不是支付完成的VC
        if let paymentDoneVC = segue.source as? PaymentCompletionVC {
            // 如果支付成功(假设第三个VC有个isPaymentSuccess的属性)
            if paymentDoneVC.isPaymentSuccess {
                // 更新数据源——要么重新从服务器拉最新的发票列表,要么修改本地数组
                self.invoices = self.getUpdatedInvoiceList()
                // 刷新TableView
                self.tableView.reloadData()
            }
        }
    }
    
  2. 在Storyboard里绑定Unwind Segue:
    找到第三个VC的“支付完成”按钮,按住Ctrl拖线到VC顶部的「Exit」图标(就是那个绿色的出口箭头),然后选择你刚才定义的unwindToInvoiceList:方法。这样点击支付按钮后,会自动回退到第一个VC,同时触发上面的更新逻辑。
方案2:闭包回调(灵活度拉满,代码可控)

如果不想依赖Storyboard的Segue,闭包是iOS开发里传递回调的常用操作,步骤也清晰:

  1. 在第二个VC(发票详情VC)里定义闭包属性:
    这个闭包用来通知第一个VC“支付完成了,该更新数据了”:
    // 用可选类型,避免没设置时崩溃
    var onPaymentFinished: (() -> Void)?
    
  2. 在第三个VC支付完成后触发闭包:
    当第三个VC处理完支付,关闭自己的时候,通知第二个VC,再由第二个VC触发闭包:
    @IBAction func confirmPaymentTapped(_ sender: UIButton) {
        // 先处理支付逻辑(比如调用接口、更新本地状态)
        // 关闭当前VC
        dismiss(animated: true) {
            // 找到上层的详情VC,触发闭包
            if let detailVC = self.presentingViewController as? InvoiceDetailVC {
                detailVC.onPaymentFinished?()
            }
        }
    }
    
  3. 在第一个VC跳转到详情VC时,设置闭包内容:
    在第一个VC的prepare(for:sender:)方法里,给详情VC的闭包赋值,指定支付完成后要做的事:
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let detailVC = segue.destination as? InvoiceDetailVC {
            // 用weak self避免循环引用
            detailVC.onPaymentFinished = { [weak self] in
                guard let self = self else { return }
                // 更新数据源+刷新TableView
                self.invoices = self.getUpdatedInvoiceList()
                self.tableView.reloadData()
            }
        }
    }
    
方案3:通知中心(适合跨多层VC的复杂场景)

如果你的VC层级更多,或者需要多个地方响应支付完成的事件,通知中心是个不错的选择:

  1. 在第一个VC里注册通知观察者:
    要记得在VC消失时移除观察者,避免内存泄漏:
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 注册通知,名字随便取,只要前后一致就行
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(updateInvoiceList),
            name: NSNotification.Name("PaymentCompleted"),
            object: nil
        )
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // 移除观察者
        NotificationCenter.default.removeObserver(self)
    }
    
    @objc private func updateInvoiceList() {
        // 更新数据源+刷新TableView
        self.invoices = self.getUpdatedInvoiceList()
        self.tableView.reloadData()
    }
    
  2. 在第三个VC支付完成后发送通知:
    @IBAction func confirmPaymentTapped(_ sender: UIButton) {
        // 处理支付逻辑
        dismiss(animated: true) {
            // 发送通知,告诉所有观察者“支付完成了”
            NotificationCenter.default.post(
                name: NSNotification.Name("PaymentCompleted"),
                object: nil
            )
        }
    }
    

个人更推荐你用方案1或者方案2,因为逻辑更直观,代码耦合度低;通知中心适合更复杂的场景,但要小心内存泄漏的问题。

内容的提问来源于stack exchange,提问作者Renan Aguiar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:51:58