如何从自定义TableViewCell刷新数据并更新CartViewController?
解决方案:在CartTableViewCell中更新CartViewController
我来给你几种常用的实现方式,都是iOS开发里组件间通信的经典方案,你可以根据场景选择:
1. 闭包(Closure)—— 简洁直观的轻量通信
这种方式代码量少,适合Cell和ViewController这种直接的父子组件通信,逻辑清晰。
步骤:
- 在
CartTableViewCell里定义一个闭包属性,用来传递删除成功的事件 - 在
CartViewController的cellForRowAt方法中,给闭包赋值,处理具体的更新逻辑 - 删除请求成功后调用闭包,通知VC更新
修改CartTableViewCell:
class CartTableViewCell: UITableViewCell { // 定义可选闭包,避免未赋值导致崩溃 var onDeleteSuccess: (() -> Void)? @IBAction func buttonDeleteAction(_ sender: UIButton) { // 先做安全校验,避免空值崩溃 guard let productId = label.text, let token = token else { return } let url = "http://aaaaaa/cart/\(productId)/del" let headers: HTTPHeaders = ["Accept":"application/json","Authorization":"Bearer \(token)"] Alamofire.request(url, method: .get, headers: headers).responseJSON { response in switch response.result { case .success(let value): let json = JSON(value) print("delete json ",json) let success = json["success"].boolValue print(success) if success { // 调用闭包通知VC执行更新 self.onDeleteSuccess?() } case .failure(let error): print(error) } } } }
在CartViewController中配置闭包:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "CartTableViewCell", for: indexPath) as! CartTableViewCell // 这里配置cell的其他内容,比如给label赋值等... // 绑定闭包,处理删除成功后的刷新逻辑 cell.onDeleteSuccess = { [weak self] in // 注意用weak self避免循环引用 guard let self = self else { return } // 1. 先更新数据源(假设cartItems是你的购物车数据数组) self.cartItems.remove(at: indexPath.row) // 2. 刷新表格 self.tableView.reloadData() // 或者如果需要从服务器重新拉取最新数据,就调用你的获取购物车列表接口 // self.fetchCartList() } return cell }
2. 代理模式(Delegate)—— iOS经典通信方式
代理是iOS里标准的组件解耦通信方式,适合逻辑更复杂、需要传递更多参数的场景。
步骤:
- 定义一个代理协议,声明删除成功的方法
- 在
CartTableViewCell中添加代理属性 - 让
CartViewController遵守该协议并实现代理方法 - 删除成功后调用代理方法通知VC
定义代理协议:
// 建议放在CartTableViewCell文件顶部 protocol CartTableViewCellDelegate: AnyObject { func cartTableViewCellDidDeleteSuccess(_ cell: CartTableViewCell) }
修改CartTableViewCell:
class CartTableViewCell: UITableViewCell { // 用weak修饰避免循环引用 weak var delegate: CartTableViewCellDelegate? @IBAction func buttonDeleteAction(_ sender: UIButton) { guard let productId = label.text, let token = token else { return } let url = "http://aaaaaa/cart/\(productId)/del" let headers: HTTPHeaders = ["Accept":"application/json","Authorization":"Bearer \(token)"] Alamofire.request(url, method: .get, headers: headers).responseJSON { response in switch response.result { case .success(let value): let json = JSON(value) print("delete json ",json) let success = json["success"].boolValue print(success) if success { // 通知代理执行更新 self.delegate?.cartTableViewCellDidDeleteSuccess(self) } case .failure(let error): print(error) } } } }
让CartViewController遵守并实现代理:
// 给类添加协议遵守 class CartViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, CartTableViewCellDelegate { // ...其他已有代码 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "CartTableViewCell", for: indexPath) as! CartTableViewCell // 设置代理 cell.delegate = self // 配置cell内容... return cell } // 实现代理方法 func cartTableViewCellDidDeleteSuccess(_ cell: CartTableViewCell) { // 通过cell获取对应的indexPath guard let indexPath = tableView.indexPath(for: cell) else { return } // 更新数据源并刷新表格 cartItems.remove(at: indexPath.row) tableView.reloadData() // 或者重新请求最新数据 // fetchCartList() } }
3. 通知中心(NotificationCenter)—— 跨组件通用方案
如果你的更新逻辑需要通知多个组件,或者Cell和VC的层级比较深,可以用通知中心,但如果只是Cell和VC之间的通信,前两种方案更高效、耦合度更低。
步骤:
- 删除成功后发送自定义通知
- 在VC中监听该通知并处理更新
在CartTableViewCell中发送通知:
if success { // 可以携带productId等参数,方便VC处理 NotificationCenter.default.post( name: NSNotification.Name("CartItemDeletedSuccess"), object: nil, userInfo: ["productId": productId] ) }
在CartViewController中监听通知:
override func viewDidLoad() { super.viewDidLoad() // ...其他代码 // 添加通知监听 NotificationCenter.default.addObserver( self, selector: #selector(handleCartItemDeleted(_:)), name: NSNotification.Name("CartItemDeletedSuccess"), object: nil ) } // 处理通知的方法 @objc func handleCartItemDeleted(_ notification: Notification) { // 从userInfo中取出参数 if let productId = notification.userInfo?["productId"] as? String { // 根据productId移除对应的数据 cartItems.removeAll { $0.id == productId } tableView.reloadData() } // 或者直接重新请求数据 // fetchCartList() } // 记得在销毁时移除监听,避免内存泄漏 deinit { NotificationCenter.default.removeObserver(self) }
以上三种方案里,闭包和代理是最推荐的,因为它们的耦合度低,逻辑清晰,适合Cell和VC这种直接的关联场景;通知中心更适合跨多个组件的通信场景。
内容的提问来源于stack exchange,提问作者Jez
相关产品推荐
相关产品推荐

