2

I've always updated the UITableViewCell content in tableView:cellForRowAtIndexPath: like this:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell:UITableViewCell = self.resultsTableView.dequeueReusableCellWithIdentifier(cellReuseIdentifier) as UITableViewCell!

    // update cell content
    cell.backgroundColor = UIColor.clearColor()
    cell.textLabel?.text = myTextString

    return cell
}

The documentation also shows content being updated in tableView:cellForRowAtIndexPath:. However, today I read

The content of the cell has to be set right before it is displayed. We don’t care which cell object is being used. All we care about is that it has the right stuff to display when it is passed on to the renderer. So, the right place to set the cell’s content is tableView:willDisplayCell:forRowAtIndexPath:

The reason for this is mentioned in the same post. It talks about the

...problem where the custom cell appears to ‘randomly change content’ when the table is scrolled. The reason why this happens is because the content of the cell is set in the tableView:cellForRowAtIndexPath: method, which is not the right place. In this method, the system expects only to obtain the cell object. Once a cell is displayed, the system will not ask for the cell object until it loses it (i.e. when the cell object is destroyed) and cannot find a replacement to reuse. If, however, a replacement is found, it is reused, and you will end up seeing the contents of that reused cell in place of the original cell.

Is that correct? I've never noticed a problem before, but should I be updating my cell content in tableView:willDisplayCell:forRowAtIndexPath:? Have I been misled by the documentation?

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • 1
    I agreed to the duplicate suggestion. If you have an answer that you think would be better here than the other question, then leave a comment and I will reopen it. – Suragch Aug 16 '16 at 22:12

1 Answers1

1

The statement is wrong.

custom cell appears to ‘randomly change content’ when the table is scrolled

occurs only if

  • dequeueReusableCellWithIdentifier is (mis)used outside cellForRowAtIndexPath.
  • The entire content of the cell is not set reliably to a defined state inside cellForRowAtIndexPath.
  • The content of the cell is manipulated outside cellForRowAtIndexPath.

The developer is strongly discouraged from using any of the three cases.

So it's perfectly fine to both supply the cell and update the content in cellForRowAtIndexPath.

PS: I guess willDisplayCell:forRowAtIndexPath: is a legacy method coming from the cell based NSTableView in macOS where the data source delegate methods don't support to change the cell's appearance.

vadian
  • 274,689
  • 30
  • 353
  • 361