【问题标题】:Counter label in UITableView Cell repeats while scrolling downUITableView 单元格中的计数器标签在向下滚动时重复
【发布时间】:2019-09-01 07:24:00
【问题描述】:

我根据加号和减号按钮计算表格视图单元格中的标签,标签值增加和减少计数,当我向下滚动时,标签在其他单元格上重复,并且单元格中的数据在上下移动时发生变化.任何人请帮我解决这个问题。谢谢

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell:CustomTableViewCell = self.customTableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! CustomTableViewCell
    cell.plusButton.tag = indexPath.row
    cell.plusButton.addTarget(self, action: #selector(BtnPlusPressed(_:)), for: .touchUpInside)
    cell.minusButton.tag = indexPath.row
    cell.minusButton.addTarget(self, action: #selector(BtnMinusPressed(_:)), for: .touchUpInside)
    cell.deviceLabel.text = self.laptop[indexPath.row]
    return cell
}

@objc func BtnPlusPressed(_ sender: AnyObject) {
    let button = sender as? UIButton
    let cell = button?.superview?.superview as? CustomTableViewCell
    let indexPath = customTableView.indexPath(for: cell!)
    if let text = cell?.countLabel.text, let value = Int(text) {
    var counter = value {
        didSet {
            cell?.countLabel.text = "\(counter)"
            print()
        }
    }
    counter += 1
    callback?(counter)
    }
}
@objc func BtnMinusPressed(_ sender: AnyObject) {
    let button = sender as? UIButton
    let cell = button?.superview?.superview as? CustomTableViewCell
    let indexPath = customTableView.indexPath(for: cell!)
    if let text = cell?.countLabel.text, let value = Int(text), value > 0  {
        var counter = value {
            didSet {
                cell?.countLabel.text = "\(counter)"
            }
        }
        counter -= 1
        callback?(counter)
    }

screenshot

【问题讨论】:

  • 单元正在重用。从顶部出去,从底部进入。和反向。
  • 您需要将值存储在底层数据模型中,而不是单元格本身中。这是因为单元格一旦滚动离开屏幕就会被重复使用。根据 cellForRow() 方法中的数据模型设置值。
  • 计数器值应该存储在一个数组中,就像您从中获取数据的笔记本电脑数组一样。单元格不应该是您保存计数器值的位置。计数器的值应该在 cellForRow 方法中获取 - 它会在每个即将被重用的单元格中调用。

标签: ios swift xcode swift4


【解决方案1】:

我真的不知道callback?(counter) 在做什么。但我认为,正如其他人已经说过的那样,通过将计数器值与数据源一起存储,可以解决您的问题。现在你的counterproperty 只存在于cellForRowblock 中。 假设您希望所有值都从零开始,并且您的模型数组称为列表。您可以执行以下操作:

var counters = [Int]()
for i in 0..<list.count {
    counters.append(0)
}

然后你的方法可能是这样的。我解开按钮以避免处理选项:

@objc func BtnMinusPressed(_ sender: AnyObject) {
    guard let button = sender as? UIButton else { return }
    let position = button.tag
    guard counters[position] > 0 else { return }
    counters[position]
    counters[position] -= 1
    cell.countLabel.text = "\(counters[position])"
    }

【讨论】:

  • 您确实在 cellForRow 中设置了按钮标签,这就是您获得位置的方式,当您执行 counters[position] -= 1 时,您正在更改数组中的位置
【解决方案2】:

细胞被重复使用。您必须保存每个单元格的计数器值。但不要使用额外的数组,而是使用自定义结构作为数据模型

struct Model {
    let name : String
    var counter = 0
}

声明数据源数组

var laptop = [Model]()

在 Swift 中,作为目标/动作的更好方法是使用回调。回调必须在表格视图单元格中声明。

在自定义单元格中添加IBactions 和回调,以便能够更新控制器中的模型。不需要按钮的插座。将操作连接到 Interface Builder 中的按钮。

class CustomTableViewCell: UITableViewCell {

    @IBOutlet weak var deviceLabel: UILabel!
    @IBOutlet weak var countLabel: UILabel!

    var callback : ((Int) -> Void)?

    var counter = 0 {
      didSet { countLabel.text = "\(counter)" }
    }

    @IBAction func plusAction(_ sender: UIButton) {
        counter += 1
        callback?(counter)
    }

    @IBAction func minusAction(_ sender: UIButton) {
        if counter > 0 { counter -= 1 }
        callback?(counter)
    }

}

cellForRow 中,将字符串值分配给 deviceLabel 并同时分配回调。每当按下其中一个按钮时,标签和模型都会更新。

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = self.customTableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! CustomTableViewCell

    let item = self.laptop[indexPath.row]
    cell.deviceLabel.text = item.name
    cell.counter = item.counter
    cell.callback = ( newValue in
        self.laptop[indexPath.row].counter = newValue
    }

    return cell
}

同时删除两个Btn...Pressed 操作。好处是没有视图层次数学,没有标签,没有objective-c-ish target/action

【讨论】:

  • 否,模型的 one 实例对应于数组中的 one 字符串(由nameproperty 表示)。您必须将字符串数组映射到模型
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多