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

如何点击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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:22:39