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

点击TableView Cell按钮更新元素:购物车数量存储与VC传值问题

购物车商品数量处理方案求助

我正为购物车中商品数量的处理寻找合适方案,已实现商品价格的增减计算函数,但不知如何正确存储数据并传递至另一个VC。我希望每次点击按钮时能改写Cell中的数量值,却不清楚正确实现方式(是否需要用数据库存储购物车数据?)。

相关代码

购物车模型结构体

struct Order:  Codable {
    let orderId: String?
    var amount: Int
    let id,name, description, image: String?
    let price : String?
}

TableViewCell中的数量增加函数

@objc func inc(){
            var into = Int(amountLabel.text!) ?? 1
            into = into + 1
        amountLabel.text = "\(into)"
            let label = DefPrice.price.components(separatedBy: "р")
            let basevalue = Int(label[0])
            priceLbl.text = "\(basevalue! * into)р."
    }

下一个VC中展示商品的代码

var dishNames = savedItems.compactMap({ "\($0.name!) \($0.price!) \($0.amount)" }) // idk how to make amount work
        let list = dishNames.joined(separator: ",\n")
        CartItems.items = list

解决方案

1. 同步Cell与数据源的数量更新

你当前的inc()函数只更新了UI显示,没有修改数据源中Order对象的amount属性,这是后续页面拿不到正确数量的核心原因。修改思路如下:

  • 给Cell绑定对应的Order对象,直接修改其amount值
  • 通过闭包回调通知ViewController更新数据源

修改后的Cell代码示例:

// 给Cell添加Order变量,初始化时同步UI
var order: Order? {
    didSet {
        amountLabel.text = "\(order?.amount ?? 1)"
        if let priceStr = order?.price, let baseValue = Int(priceStr.components(separatedBy: "р")[0]) {
            priceLbl.text = "\(baseValue * (order?.amount ?? 1))р."
        }
    }
}
// 数量变化的回调闭包
var onAmountChanged: ((Int) -> Void)?

@objc func inc(){
    guard var currentOrder = order else { return }
    currentOrder.amount += 1
    // 更新数据源对象
    order = currentOrder
    // 更新UI
    amountLabel.text = "\(currentOrder.amount)"
    if let priceStr = currentOrder.price, let baseValue = Int(priceStr.components(separatedBy: "р")[0]) {
        priceLbl.text = "\(baseValue * currentOrder.amount)р."
    }
    // 通知ViewController更新数据源
    onAmountChanged?(currentOrder.amount)
}

在ViewController的cellForRowAt方法中绑定回调:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "CartCell", for: indexPath) as! CartCell
    let targetOrder = savedItems[indexPath.row]
    cell.order = targetOrder
    cell.onAmountChanged = { [weak self] newAmount in
        guard let self = self else { return }
        // 更新数据源中的对应商品数量
        self.savedItems[indexPath.row].amount = newAmount
        // 可选:同步持久化数据
        self.saveCartData()
    }
    return cell
}

2. 购物车数据存储方案

  • 临时存储(APP运行期间):用UserDefaults存储序列化后的数组即可,因为Order已实现Codable:
// 保存购物车数据
func saveCartData() {
    if let encodedData = try? JSONEncoder().encode(savedItems) {
        UserDefaults.standard.set(encodedData, forKey: "CartSavedItems")
    }
}

// 加载购物车数据
func loadCartData() {
    if let savedData = UserDefaults.standard.data(forKey: "CartSavedItems") {
        savedItems = try? JSONDecoder().decode([Order].self, from: savedData) ?? []
    }
}
  • 持久化存储(重启APP仍保留):如果购物车数据量大或需要复杂查询,推荐用Core Data或Realm,但初期用UserDefaults完全够用。

3. 页面间数据传递

直接传递savedItems数组即可,无需拼接字符串:

在目标VC中定义变量:

var cartItems: [Order]?

跳转时传递数据:

let nextVC = storyboard?.instantiateViewController(withIdentifier: "NextVC") as! NextVC
nextVC.cartItems = savedItems
navigationController?.pushViewController(nextVC, animated: true)

目标VC中展示数据:

override func viewDidLoad() {
    super.viewDidLoad()
    guard let items = cartItems else { return }
    let dishNames = items.compactMap { "\($0.name ?? "") \($0.price ?? "") \($0.amount)" }
    let list = dishNames.joined(separator: ",\n")
    CartItems.items = list
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 05:02:59