dequeueReusableCellWithIdentifier创建新单元格而不是重用单元格

时间:2016-01-17 19:52:37

标签: ios uitableview custom-cell

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

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

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

diagram example

当点击UIButton时(多次调用该动作),并且通过“轻扫以删除”动作,新的第二个单元格可以覆盖已刷过的单元格,这会产生问题看起来删除按钮随机消失。

我该如何解决这个问题?

修改

代码自定义单元格

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()

   }

扩展名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
}

buttonAction:

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

我将代码缩小到最大值,注意在进一步调查后按钮打印了相同的文本,因为我的一个错误我写了两次消息^^' 因此剩下的唯一问题是“滑动删除”手势

1 个答案:

答案 0 :(得分:1)

如果我理解正确,那么保持(结果)动作与tableView中显示的内容同步有问题。

    1. 了解UITableView如何使用单元格:它会向它的dataSource询问UITableViewCell。您可以每次创建一个,也可以要求tableView重用一个。由于这种机制,您创建的单元格可以一次出现在某个位置,稍后出现在另一个位置。
    1. 确保您的逻辑和数据始终独立于实际的tableViewCells。因此,您应该只使用NSIndexPath执行所需操作。
    1. UITableViewCell可以通过两种方法-indexPathForCell:indexPathForRowAtPoint:之一为tableViewCell提供有效的indexPath。

在UITableViewCells上处理操作的方法如下:

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

虽然这对于一件小事来说似乎有很多工作,但实际上并没有那么多工作,而且你的代码会更强大,更容易理解并且更少耦合。