如何点击CustomBottomSheet按钮将数据传递至购物车页面TableView
iOS 商品数据从CustomBottomSheet传递到AddviewController的解决方案
方案一:闭包(Closure)传递
适合一对一的页面数据传递,实现简洁直接。
步骤1:在CustomBottomSheet中定义闭包属性
class CustomBottomSheet: UIViewController { // 定义接收数据的闭包,参数根据实际数据结构调整 var addToCartHandler: ((_ productName: String, _ quantity: Int, _ totalPrice: Double) -> Void)? // 「加入购物车」按钮点击事件 @IBAction func addToCartButtonTapped(_ sender: UIButton) { // 假设已获取当前选中的商品数据 let selectedName = "XX商品" let selectedQty = 2 let total = 99.8 // 触发闭包传递数据 addToCartHandler?(selectedName, selectedQty, total) // 关闭BottomSheet dismiss(animated: true) } }
步骤2:在AddviewController中绑定闭包并处理数据
class AddviewController: UIViewController { // 存储购物车数据,用于驱动tableView刷新 var cartItems: [(name: String, quantity: Int, price: Double)] = [] @IBOutlet weak var addTableView: UITableView! // 弹出CustomBottomSheet的方法 func showBottomSheet() { let bottomSheet = CustomBottomSheet() bottomSheet.addToCartHandler = { [weak self] name, qty, price in guard let self = self else { return } // 添加数据到购物车数组 self.cartItems.append((name, qty, price)) // 刷新tableView self.addTableView.reloadData() } // 按实际方式弹出BottomSheet,这里以模态为例 present(bottomSheet, animated: true) } // MARK: - UITableView 数据源方法 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return cartItems.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "ADDTableViewCell", for: indexPath) as! ADDTableViewCell let item = cartItems[indexPath.row] // 给cell的UI组件赋值 cell.productNameLabel.text = item.name cell.quantityLabel.text = "x\(item.quantity)" cell.totalPriceLabel.text = String(format: "¥%.2f", item.price) return cell } }
方案二:代理(Delegate)模式
适合需要规范交互逻辑、扩展性更强的场景。
步骤1:定义代理协议
protocol CustomBottomSheetDelegate: AnyObject { func bottomSheetDidAddToCart(_ sheet: CustomBottomSheet, productName: String, quantity: Int, totalPrice: Double) }
步骤2:在CustomBottomSheet中添加代理属性
class CustomBottomSheet: UIViewController { weak var delegate: CustomBottomSheetDelegate? @IBAction func addToCartButtonTapped(_ sender: UIButton) { let selectedName = "XX商品" let selectedQty = 2 let total = 99.8 // 调用代理方法传递数据 delegate?.bottomSheetDidAddToCart(self, productName: selectedName, quantity: selectedQty, totalPrice: total) dismiss(animated: true) } }
步骤3:在AddviewController中实现代理
class AddviewController: UIViewController, CustomBottomSheetDelegate { var cartItems: [(name: String, quantity: Int, price: Double)] = [] @IBOutlet weak var addTableView: UITableView! func showBottomSheet() { let bottomSheet = CustomBottomSheet() bottomSheet.delegate = self present(bottomSheet, animated: true) } // 实现代理方法 func bottomSheetDidAddToCart(_ sheet: CustomBottomSheet, productName: String, quantity: Int, totalPrice: Double) { cartItems.append((productName, quantity, totalPrice)) addTableView.reloadData() } // 省略tableView数据源方法(同方案一) }
方案三:通知中心(NotificationCenter)
适合跨多层级页面的数据传递,注意避免内存泄漏。
步骤1:在CustomBottomSheet中发送通知
class CustomBottomSheet: UIViewController { @IBAction func addToCartButtonTapped(_ sender: UIButton) { let selectedName = "XX商品" let selectedQty = 2 let total = 99.8 // 封装数据到字典 let userInfo: [String: Any] = [ "productName": selectedName, "quantity": selectedQty, "totalPrice": total ] // 发送通知 NotificationCenter.default.post(name: NSNotification.Name("AddToCartNotification"), object: nil, userInfo: userInfo) dismiss(animated: true) } }
步骤2:在AddviewController中监听通知
class AddviewController: UIViewController { var cartItems: [(name: String, quantity: Int, price: Double)] = [] @IBOutlet weak var addTableView: UITableView! override func viewDidLoad() { super.viewDidLoad() // 注册通知监听 NotificationCenter.default.addObserver(self, selector: #selector(handleAddToCart(_:)), name: NSNotification.Name("AddToCartNotification"), object: nil) } @objc func handleAddToCart(_ notification: Notification) { guard let userInfo = notification.userInfo, let name = userInfo["productName"] as? String, let qty = userInfo["quantity"] as? Int, let price = userInfo["totalPrice"] as? Double else { return } cartItems.append((name, qty, price)) addTableView.reloadData() } deinit { // 页面销毁时移除通知监听,防止内存泄漏 NotificationCenter.default.removeObserver(self) } // 省略tableView数据源方法(同方案一) }
注意事项
- 使用闭包和代理时,必须用
[weak self]避免循环引用。 - 通知中心务必在页面销毁时移除监听,否则会引发内存泄漏。
- 确保
ADDTableViewCell的UI控件已正确关联IBOutlet,避免赋值时出现空指针问题。
内容的提问来源于stack exchange,提问作者acacia
相关产品推荐
相关产品推荐

