Josh Kahane
Josh Kahane

Reputation: 17160

UITableView Reuse Causing Broken Cells

When scrolling my UITableView (tends to be when I scroll it fast) the data for my cells gets mixed up, so labels might be repeated etc.

I understand that reusing the cells probably causes this, but what if the user scrolls down the list really quickly and all the cells get mixed up, how am I supposed to avoid this?

Thanks.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"VideoListCell";
    VideoListCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[VideoListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...
    if (isPlaylistView)
    {
        //Fill cell with data
    }
    else if (isPlaylistDetailView || isSearchResultsView)
    {
        //Fill cell with data
    }
    else
    {
        //Playlist button and uploads
        if (indexPath.section == 0)
        {
            //Fill cell with data
        }
        else
        {
            //Fill cell with data
        }
    }

    return cell;
}

Upvotes: 0

Views: 551

Answers (5)

Abid Hussain
Abid Hussain

Reputation: 1549

In your custom cell class override prepareForReuse method. In this method set text of your labels to nil and set imageview's image to nil also. This function is called everytime when a cell is reused so your problem will be solved by this. May be like this

- (void)prepareForReuse{
    [super prepareForReuse];
    self.titleLabel.text = nil;
    self.unitImageView.image = nil;
}

Upvotes: 0

Paras Joshi
Paras Joshi

Reputation: 20541

set dequeueReusableCellWithIdentifier to nil for example..

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];

UPDATE:

See this Example... i load many data in the cell with also my custom Gridview...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{    
    static NSString* cellIdentifier = @"gridCell";

    UITableViewCell *gridCell = [tableView dequeueReusableCellWithIdentifier:nil];

    if(gridCell == nil)        
    {
        gridCell =  [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];


    }
    return gridCell;
}

hope this help you....

Upvotes: 0

Prasad G
Prasad G

Reputation: 6718

static NSString *cellIdentifier=@"cell";
    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if(cell==nil)
    {
        cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
    }

I think it will be helpful to you.

Upvotes: 0

bealex
bealex

Reputation: 10014

You generally use this kind of code:

cell = dequeReusableCell;
if (cell == nil) { 
    create cell;
    initialize cell;
}

fill cell with actual data from current row
return cell;

If you will move code "fill cell with actual data from current row" into "if" — you will get the kind of behavior you get right now.

So the answer will be "fill cell with data after you initialize it, outside of "if (cell == nil)" block.

Upvotes: 2

tom
tom

Reputation: 19153

UITableView will ever only dequeue a cell for reuse if the position that the cell was in is currently off-screen. So you don't have to worry about "mix-ups".

Upvotes: 0

Related Questions