如何从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
相关产品推荐
相关产品推荐

