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

如何从MainViewController调用WalletViewController中UITableView触发的钱包更新函数

我来给你几个实用的解决方案,帮你搞定在MainViewController里触发WalletViewController钱包数值更新的问题,同时保证两个页面的数值同步~

方案1:抽离钱包数据为单例模型(最推荐,代码解耦首选)

把钱包的状态和更新逻辑从ViewController中抽离成独立的单例类,这样所有页面都能直接获取最新数据,不用互相依赖ViewController:

  • 第一步:创建WalletManager单例类,封装钱包数据和更新逻辑
class WalletManager {
    // 全局唯一实例
    static let shared = WalletManager()
    private init() {}
    
    // 钱包当前数值
    var currentAmount: Double = 0.0
    
    // 你的钱包数值更新逻辑
    func calculateLatestWalletAmount() {
        // 这里写原来根据钱包内容计算数值的逻辑,比如遍历物品求和
        // currentAmount = 计算后的结果
    }
}
  • 第二步:在WalletViewController中,原来触发更新的时机(比如tableView reload时)调用单例方法
// WalletViewController中tableView相关方法示例
func tableView(_ tableView: UITableView, didReloadRowsAt indexPaths: [IndexPath]) {
    WalletManager.shared.calculateLatestWalletAmount()
    // 同时更新WalletVC自身的UI
    walletAmountLabel.text = String(format: "¥%.2f", WalletManager.shared.currentAmount)
}
  • 第三步:在MainViewController中,用户触发刷新时直接调用单例方法,然后同步UI
// MainViewController中用户点击刷新按钮或下拉刷新的方法
func handleRefreshAction() {
    WalletManager.shared.calculateLatestWalletAmount()
    // 更新MainVC上的钱包数值展示
    mainWalletLabel.text = String(format: "¥%.2f", WalletManager.shared.currentAmount)
}

这种方式让所有页面共享同一个数据源,天然保证数值同步,代码结构也更清晰。

方案2:使用NotificationCenter(通知中心,适合快速实现)

如果暂时不想重构数据模型,可以用通知让两个页面互相触发更新:

  • 第一步:定义专属通知名称
extension Notification.Name {
    // 通知WalletVC更新钱包数值
    static let requestWalletUpdate = Notification.Name("RequestWalletUpdate")
    // 通知所有页面钱包数值已更新
    static let walletAmountUpdated = Notification.Name("WalletAmountUpdated")
}
  • 第二步:在WalletViewController中监听更新请求,完成更新后通知其他页面
override func viewDidLoad() {
    super.viewDidLoad()
    // 监听更新请求通知
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(updateWalletAmount),
        name: .requestWalletUpdate,
        object: nil
    )
}

// 你的钱包数值更新函数
@objc private func updateWalletAmount() {
    // 执行原来的数值计算逻辑
    let calculatedAmount = 0.0 // 替换成你的计算结果
    // 更新WalletVC自身UI
    walletAmountLabel.text = String(format: "¥%.2f", calculatedAmount)
    // 通知其他页面数值已更新
    NotificationCenter.default.post(
        name: .walletAmountUpdated,
        object: nil,
        userInfo: ["amount": calculatedAmount]
    )
}

// 记得在销毁时移除监听
deinit {
    NotificationCenter.default.removeObserver(self)
}
  • 第三步:在MainViewController中发送更新请求,并监听数值更新完成的通知
override func viewDidLoad() {
    super.viewDidLoad()
    // 监听数值更新完成的通知
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(refreshMainWalletUI(_:)),
        name: .walletAmountUpdated,
        object: nil
    )
}

// 用户触发刷新时发送更新请求
func handleUserRefresh() {
    NotificationCenter.default.post(name: .requestWalletUpdate, object: nil)
}

// 收到更新通知后刷新MainVC的UI
@objc private func refreshMainWalletUI(_ notification: Notification) {
    if let amount = notification.userInfo?["amount"] as? Double {
        mainWalletLabel.text = String(format: "¥%.2f", amount)
    }
}

deinit {
    NotificationCenter.default.removeObserver(self)
}
方案3:代理/闭包(适合两个VC有明确导航关系的场景)

如果MainViewController和WalletViewController存在导航栈关联(比如MainVC push到WalletVC),可以用代理直接调用方法:

  • 第一步:定义更新代理协议
protocol WalletUpdateDelegate: AnyObject {
    func updateWalletAmount() -> Double
}
  • 第二步:在WalletViewController中实现协议方法,并暴露代理属性
class WalletViewController: UIViewController {
    weak var delegate: WalletUpdateDelegate?
    
    // 你的数值更新逻辑,返回最新数值
    func updateWalletAmount() -> Double {
        let calculatedAmount = 0.0 // 替换成你的计算结果
        walletAmountLabel.text = String(format: "¥%.2f", calculatedAmount)
        return calculatedAmount
    }
}
  • 第三步:在MainViewController中获取WalletVC实例,调用更新方法并同步UI
// 从导航栈中找到WalletVC实例
private func findWalletViewController() -> WalletViewController? {
    for vc in navigationController?.viewControllers ?? [] {
        if let walletVC = vc as? WalletViewController {
            return walletVC
        }
    }
    return nil
}

// 用户触发刷新时调用
func handleRefresh() {
    guard let walletVC = findWalletViewController() else { return }
    let latestAmount = walletVC.updateWalletAmount()
    mainWalletLabel.text = String(format: "¥%.2f", latestAmount)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:03:07