点击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
相关产品推荐
相关产品推荐

