外卖App购物车显示异常:新增商品覆盖所有商品名称问题
嘿,这个问题其实很典型——你现在的购物车条目里只存了ProductSize和数量,但没把对应的Product信息关联进去,而且CartController里的product变量是个单个实例,每次用户从商品页跳过来,这个变量都会被新的商品覆盖,所以所有购物车单元格都只能拿到最后一次传过来的商品名称啦!
问题根源拆解
你看,在CartController的cellForRowAt方法里,你是直接用self.product?.name来设置商品名称的:
let pname = self.product cell.lblName.text = pname?.name
这个self.product是每次跳转时通过prepare(for:sender:)传过来的单个商品对象,每次添加新商品都会把它替换成最新的那个,自然所有单元格都会显示最后添加的商品名称。
而且你的Cart的items里应该只保存了ProductSize和数量,没有关联对应的Product,所以没法从购物车条目里拿到每个商品自己的名称。
一步步解决
1. 修改购物车条目(CartItem)的结构
首先,你需要让每个购物车条目同时保存对应的Product、ProductSize和数量。假设你的CartItem是这样的,现在要加上Product属性:
class CartItem { var product: Product var productSize: ProductSize var qty: Int init(product: Product, productSize: ProductSize, qty: Int) { self.product = product self.productSize = productSize self.qty = qty } }
2. 添加商品到购物车时,同时传入Product
当用户选择商品规格添加到购物车的时候,要把当前的Product对象也一起传进去,比如在商品详情页的添加逻辑里:
// 假设这是你添加到购物车的代码 let selectedSize = // 用户选中的ProductSize实例 let newItem = CartItem(product: self.product, productSize: selectedSize, qty: 1) Cart.currentCart.items.append(newItem)
3. 修改CartController的cellForRowAt方法
现在,你可以直接从当前的购物车条目里取出对应的Product,而不是用全局的self.product了:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "shoppingCartCell", for: indexPath) as! CartCell let cartItem = Cart.currentCart.items[indexPath.row] cell.lblQty.text = "\(cartItem.qty)" cell.lblTotal.text = "$\(cartItem.productSize.price! * Float(cartItem.qty))" // 从当前条目里取对应的商品名称 cell.lblName.text = cartItem.product.name return cell }
4. 移除CartController里的多余product变量
现在你不需要再通过prepare(for:sender:)传product到CartController了,因为购物车条目里已经包含了所有需要的信息,所以可以删掉CartController里的这个变量:
// 删掉这行多余的代码 var product: Product?
同时,前一个视图控制器的prepare(for:sender:)里关于传product的代码也可以一并删除。
这样修改之后,每个购物车条目都会关联自己对应的商品信息,不管添加多少种商品,单元格都会正确显示各自的名称啦!
内容的提问来源于stack exchange,提问作者Doing Things Occasionally

