滚动时如何更新UITableView数据?购物车数据复原问题
解决UITableView滚动后购物车数据恢复初始状态的问题
这个问题是UITableView复用机制的典型坑——你修改cell显示的数量和价格后,没有同步更新底层的数据源,当cell被滚动回收再复用的时候,cellForRowAt又会从原始数据源里取数据,自然就回到初始状态了。结合你的代码,我给你一步步改:
1. 给CartModel添加数量存储属性
首先得在CartModel里加一个quantity字段(比如var quantity: Int?),用来存储当前商品的数量——原来的代码里根本没地方存修改后的数量,这是核心问题!
2. 修改ViewModel,添加直接更新数据源的方法
在ChartViewModel里新增一个更新商品数量的方法,不用绕弯子做搜索:
// 更新指定位置商品的数量(+1),同步计算总价 func updateProductQuantity(at index: Int) { guard let product = datasourceModel.dataListArray?[index] else { return } // 数量+1,默认初始为1 let newQuantity = (product.quantity ?? 1) + 1 product.quantity = newQuantity // 计算新的总价:根据你的模型属性调整,这里假设cartpriceInt是单价,cartsumint是总价 if let unitPrice = product.cartpriceInt { let newTotal = unitPrice * newQuantity product.cartsumint = newTotal product.carttotalprice = "QR \(newTotal)" } // 重新计算购物车总价格 totalPriceInCart() }
3. 修正Cell的setEventData方法
你现在在cell里硬把步进器值设为1了,这完全不对!要从数据源读取当前的数量:
func setEventData(carts: CartModel) { self.name.text = carts.cartname // 直接用数据源里的最新总价 self.price.text = carts.carttotalprice // 步进器的值设为数据源里的当前数量,不是固定1! self.itemQuantityStepper.value = Double(carts.quantity ?? 1) // 原来的打印代码可以保留,但不要硬改价格,完全依赖数据源 print(self.price.text) }
4. 重构cellForRowAt里的闭包逻辑
原来的search逻辑完全没必要,直接通过indexPath定位数据源里的商品就行:
cell.cartadd = { [weak self] cell in guard let self = self, let indexPath = self.tableView.indexPath(for: cell) else { return } // 先更新数据源里的商品数据 self.chartViewModel.updateProductQuantity(at: indexPath.row) // 只刷新当前行,避免全局刷新卡顿 self.tableView.reloadRows(at: [indexPath], with: .automatic) // 更新总价显示 let totalPrice = self.chartViewModel.totalvalue.first ?? 0 self.totalresult.text = "QR \(totalPrice)" }
关键原理再强调
UITableView的cell是复用的,它的显示内容完全依赖你传给它的数据源。你之前只改了cell上的控件值,但没修改数据源里的模型,所以滚动后cell被重新初始化时,又会从原始数据源拿数据,自然恢复初始状态。只要保证数据源和UI显示完全同步,修改数据时先更新数据源,再刷新对应UI,就不会有这个问题了。
内容的提问来源于stack exchange,提问作者brucecraigb
相关产品推荐
相关产品推荐

