【问题标题】:dequeueReusableCellWithIdentifier creating a new cell instead of reusing onedequeueReusableCellWithIdentifier 创建一个新单元格而不是重用一个单元格
【发布时间】:2016-01-17 19:52:36
【问题描述】:

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

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

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

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

   }

随机颜色扩展代码

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)")
}

我将代码减少到最大,在进一步调查后请注意,由于我的一个错误,按钮打印了相同的文本我写了两次消息^^' 所以剩下的唯一问题是“滑动删除”手势

【问题讨论】:

  • 用cellForRowAtIndexPath 方法更新您的问题。还要确保自定义单元格类中的 prepareForReuse 方法正确重置单元格的状态。

标签: ios uitableview custom-cell


【解决方案1】:

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

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

UITableViewCells上的action处理方式如下:

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

虽然这对于一件小事来说似乎需要做很多工作,但实际上并没有那么多工作量,而且您的代码会更加健壮、更容易理解并且耦合更少。

【讨论】:

  • 好的,我知道当按钮被触摸时使用委托来获取
  • OK 我只需要检查单元格的editingStyle == .None
猜你喜欢
  • 2013-01-05
  • 2013-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-07
  • 1970-01-01
相关资源
最近更新 更多