dequeueReusableCellWithIdentifier 创建一个新单元格而不是重复使用一个单元格

dequeueReusableCellWithIdentifier creating a new cell instead of reusing one

我在带有自定义单元格的 UIViewController 中使用了 UITableView。但是,当调用 dequeueReusableCellWithIdentifier 时,它有时会创建一个新单元格而不是重复使用现有单元格。

例如:当第一个单元格第一次更新时,将创建一个新单元格而不是重新使用原始单元格。

我创建了一个图表来帮助更好地说明问题。每个绿色矩形是一个应该发生的动作,每个红色矩形是一个不应该发生的动作。每个箭头都是 dequeueReusableCellWithIdentifier.

的调用

点击UIButton时有问题(多次调用该动作),而使用"swipe to delete"动作时,已滑动的单元格可以被新的第二个单元格覆盖,这使得删除按钮看起来像是随机消失。

我该如何解决这个问题?

编辑:

代码自定义单元格

class TableViewCell : UITableViewCell{
   @IBOutlet weak var buttonStop: UIButton!
   required init?(coder aDecoder: NSCoder) {
       super.init(coder: aDecoder)
       print("newCell")
       backgroundColor = color
   }
   override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
       super.init(style: style, reuseIdentifier: reuseIdentifier)
   }
   override func prepareForReuse() {
       super.prepareForReuse()

   }
   var color = UIColor().randomColor()

   }

扩展随机颜色的代码

extension UIColor {
func randomColor() -> UIColor {
    let aRedValue = CGFloat(arc4random()) % 255 / 255
    let aGreenValue = CGFloat(arc4random()) % 255 / 255
    let aBlueValue = CGFloat(arc4random()) % 255 / 255
    return UIColor(red: aRedValue, green: aGreenValue, blue: aBlueValue, alpha: 1)
}

cellForRow 代码

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell",forIndexPath: indexPath) as! TableViewCell
    cell.buttonStop.tag = indexPath.row
    cell.buttonStop.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)
    return cell
}

按钮动作:

func buttonAction(sender: UIButton) {
    print("action for cell : \(sender.tag)")
}

我将代码减少到最大值,进一步调查后发现按钮打印了相同的文本,因为我的一个错误我写了两次消息 ^^' 所以剩下的唯一问题是 "swipe to delete" 手势

如果我理解正确的话,您在将操作(的结果)与 tableView 中显示的内容保持同步时遇到了问题。

    1. 了解 UITableView 如何使用单元格:它会询问 UITableViewCell 的数据源。您可以每次都创建一个,也可以向 tableView 索取一个以供重复使用。由于这种机制,您创建的单元格可以先出现在某个位置,然后再出现在另一个位置。
    1. 确保您的逻辑和数据始终独立于实际的 tableViewCells。所以你应该能够只用一个 NSIndexPath 来做你必须做的事情。
    1. UITableViewCell 可以通过以下两种方法之一为您提供 tableViewCell 的有效索引路径 -indexPathForCell:indexPathForRowAtPoint:.

UITableViewCells的动作处理方式如下:

    1. 创建 UITableViewCell
    2. 的自定义子class
    1. 在此子class中创建协议(例如MyCellDelegate
    1. 给这个 class 一个类型为 id <MyCellDelegte>
    2. 的 属性 delegate
    1. 在您的数据源中创建单元格时,将此数据源签名为该单元格的委托。
    1. 让这个 subclass 通过在它的委托(委托是你的数据源)上调用协议中的方法来处理操作(滑动/点击)。
    1. 在该委托方法的实现中(在您的数据源上),您可以调用 UITableView 上的方法之一来获取 indexPath。这是您变得独立于实际 tabelViewCell 的点:使用该 indexPath 获取数据,或执行特定操作。

尽管这对于一件小事来说似乎需要做很多工作,但实际上并没有那么多工作,而且您的代码将更加健壮、更易于遵循且耦合度更低。