Swift 当滚动影响内部数据时调用reloadData()

Swift 当滚动影响内部数据时调用reloadData(),swift,uitableview,uistepper,Swift,Uitableview,Uistepper,因此,Swift中的表视图似乎会根据滚动位置动态地将数据重新加载到屏幕上。但是,在我的例子中,我不希望该机制以这种方式工作,因为我的表视图中的项目更新了用户订单的总价,并且不必要地增加了总价。当我向上或向下滚动时,调用重新加载数据的单元格正在重新形成数学,并导致不正确的总价 我希望仅当在特定单元格上按UIStepper而不是滚动时,才使用reloadData()函数重新计算价格。我通过一个iAction函数来实现这一点,该函数在按下步进器时调用reloadData。数学和内部数据的问题发生在滚动

因此,Swift中的表视图似乎会根据滚动位置动态地将数据重新加载到屏幕上。但是,在我的例子中,我不希望该机制以这种方式工作,因为我的表视图中的项目更新了用户订单的总价,并且不必要地增加了总价。当我向上或向下滚动时,调用重新加载数据的单元格正在重新形成数学,并导致不正确的总价

我希望仅当在特定单元格上按UIStepper而不是滚动时,才使用
reloadData()
函数重新计算价格。我通过一个iAction函数来实现这一点,该函数在按下步进器时调用
reloadData
。数学和内部数据的问题发生在滚动表视图时,并且在可见单元格更改时反复调用
reloadData
函数,我不希望它以任何形式滚动

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let add_on = JSON(self.add_ons[indexPath.row])
        let cell = tableView.dequeueReusableCell(withIdentifier: "AddOnCell", for: indexPath) as! AddOnTableViewCell

        quantities[indexPath.row] = cell.quantity
        //cell.quantityLabel.text = String(quantities[indexPath.row])

        let price = Double(add_on["price"].int!)/100.0
        let quantity:Double = Double(quantityLabel.text!)!

        //when user tries to increase add-on quantity beyond ticket quantity
        if(Int(quantity) < cell.quantity){
            print("QUANTITY UPDATED")
            cell.quantity -= 1
            quantities[indexPath.row] = cell.quantity
        }
        self.addOnPrice = updateTotal(quantities: self.quantities)
        totalPriceLabel.text = (Double(event_subtotal * quantity) + addOnPrice).dollarRound()

        cell.addonLabel?.text = add_on["name"].string! + " (+$\(price.roundTo(places: 2))" + ")"

        return cell
}

func updateTotal(quantities: [Int]) -> Double{
    var result:Double = 0.0
    for i in 0..<quantities.count{
        let curr_addon = JSON(self.add_ons[i])
        let price = Double(curr_addon["price"].int!)/100.0
        result += Double(quantities[i]) * price
    }
    return result.dollarRoundDouble()
}

@IBAction func stepperClicked(_ sender: UIStepper) {
    self.addOnPrice = 0.0
    AddOnTableView.reloadData()
}
行为:滚动时,计算出的总价格在没有步进器交互的情况下发生变化。根据滚动位置,1个项目的数量与另一个项目的数量值“交换”。由于某种原因,第一项数量变为1会更新最后一项的数量。无法调试此行为

供参考的用户界面

在UIKit中,单元格在滚动列表时被重复使用。假设单元格值只是来来去去去。它不应该持有长期价值。总计的计算不应采用
cellForRow
方法。首先,您缺少一个保存所有数据的数据模型。这样做的方法是创建一个表示附加组件的结构(具有数量、价格等)。当接收到json时,您将解析所有json并将其存储在数组中。然后将该阵列用作主源。
cellForRow
应该使用那里的数据,并将结构传递给
AddOnTableViewCell
,这样所有内容都可以很好地分离。当用户点击数量步骤时,它应该调用您创建的委托类,该类在视图控制器中实现,该类使用更新的数量更新数组,然后进行合计。假设单元格值只是来来去去去

因此,创建一个新类:

protocol AddOnUpdated: class {
    func quantityUpdated(label: String, value: Int)
}
然后将成员添加到您的单元格中{

class AddOnTableViewCell: UITableViewCell{
  weak var delegate: AddOnUpdated?

  func quantityStep {
     .. same code
     delegste?.quantityUpdated(label, value)
  }
}
然后在视图控制器中,创建单元格时不要更新总计。只需执行委托,并在创建单元格时将
委托
值设置为
自我

现在,只要更新任何单元格的值,就应该调用委托。此时,您需要更新您的值数组,并更新总数


希望所有这些都有意义。

这听起来像是细胞重用的问题。你能分享你的表视图委托代码吗?谢谢你的回答。我继续用UI屏幕截图和源代码更新了问题。如果任何部分没有意义,让我知道,我可以澄清。哪个变量包含总价?如果inteFace看起来总是这样的,使用静态单元格可能更容易(即使用IB而不是在代码中创建单元格)。此外,最好不要将数据模型内容(数量)作为UI元素(单元格)的属性。数据模型应该在幕后不可见,并且从中获取的数据显示在单元格中。我正在考虑解决这个问题的方法。
totalPriceLabel
是包含总价的标签。
self.addOnPrice
是在小计之上添加的内容,用于计算总价。如果您不介意,您能完成这个任务吗更新数量的ce代码,并使用更新的值调用代理?我还是新手,您的实现不是很清楚。能否请您使用更完整的源代码片段支持您的解决方案?我正在尝试尽快解决此错误,以便我可以为我的应用程序转移到其他未决任务。因此,让我看看我是否正确理解了这一点…(1)根据从JSON接收到的数据,在对象(结构)上创建一个包含数量、标题和价格的add_数组使用
addonUpdate
函数在my view controller中实现协议
addonUpdate
,该函数更新我们从JSON数据构建的数组中相应插件的数量,并计算总c。
class AddOnTableViewCell: UITableViewCell{
  weak var delegate: AddOnUpdated?

  func quantityStep {
     .. same code
     delegste?.quantityUpdated(label, value)
  }
}