VTS12
VTS12

Reputation: 452

Excess UITableView cells

I have a custom UITableViewCell that seems to appear multiple times on my table before I even start scrolling. It seems dequeueReusableCellWithIdentifier isn't working properly. Here's my cell:

MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    ... setup ...
}

When I call reloadRowsAtIndexPaths: on my tableView, for some reason it doesn't dequeue that cell and it recreates the new one. Then when I scroll back up and then down again, sometimes my first cell dequeues, sometimes the second cell dequeues. MyCustomCell is basically a textfield so depending on which one dequeues, the text has different data each time.

Is there something more I should be doing in my custom cell? Thanks in advance.

Upvotes: 0

Views: 190

Answers (2)

rob mayoff
rob mayoff

Reputation: 385650

You mention reloadRowsAtIndexPaths: in your question, but the method is actually reloadRowsAtIndexPaths:withRowAnimation:. The fact that the reload can be animated matters. For example, to animate UITableViewRowAnimationLeft, the table view needs to slide out an old cell while sliding in a new cell. Both the old and new cells are on screen simultaneously, so the table view can't just use the same UITableViewCell object for both. That's why “it doesn't dequeue that cell and it recreates the new one”. It needs a new one because the old one is still visible.

You need to make sure that when you receive a tableView:cellForRowAtIndexPath: message, you fully initialize the cell (whether dequeued or newly created) to show the data for the requested row, and only the data for the requested row.

Also, you can't keep your own mapping from the row's indexPath to the cell, because (during animations) there may be two cells for the same row. Instead, if at any time you need to get the cell that is currently showing the data for a row, you need to ask the table view for the cell by sending it a cellForRowAtIndexPath: message.

Upvotes: 1

Phillip Mills
Phillip Mills

Reputation: 31016

From the code you show, it looks as if you only set up your cell's content when a new one is created. Since there's no way of knowing which cell you'll be given from the cache, you need to configure the cell whether it's new or one that's being re-used.

Upvotes: 0

Related Questions