7

I have a UITableView and I've subclassed UITableViewCell (called it CustomCell) so it has several labels and a UIImageView.

Only certain cells will actually display an image. Here's my code for tableView:cellForRowAtIndexPath::

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    Match *aMatch = [[appDelegate.matchByDate objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
    static NSString *CellIdentifier = @"Cell";


    CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }


    cell.homeLabel.text = aMatch.homeTeam;
    cell.awayLabel.text = aMatch.awayTeam;
    cell.timeLabel.text = aMatch.koTime;
    cell.tournamentLabel.text = aMatch.tournament;


    NSString *tempString = [appDelegate.teamLogos objectForKey:[aMatch homeTeam]];
    if (tempString!=nil) {
        cell.homeImageView.image = [UIImage imageNamed:tempString];
    }

    return cell;
}

So it only sets the homeImageView when it finds a corresponding image in a dictionary I have set up. This seems to work for the first few cells, but if I scroll through the list I find cells have an image when they shouldn't have one.

I understand this is probably because of the cell being re-used, but I'm setting the homeImageView after the cell has been created/reused?!

Here's the init method from my CustomCell Class

    - (id)initWithStyle:(UITableViewCellStyle)style
    reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        // Initialization code
        tournamentLabel = [[UILabel alloc] init];
        tournamentLabel.textAlignment = UITextAlignmentCenter;
        tournamentLabel.font = [UIFont systemFontOfSize:12];
        tournamentLabel.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];  
        tournamentLabel.textColor = [UIColor darkGrayColor];
        homeLabel = [[UILabel alloc]init];
        homeLabel.textAlignment = UITextAlignmentLeft;
        homeLabel.font = [UIFont systemFontOfSize:16];
        homeLabel.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];
        awayLabel = [[UILabel alloc]init];
        awayLabel.textAlignment = UITextAlignmentRight;
        awayLabel.font = [UIFont systemFontOfSize:16];
        awayLabel.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];
        timeLabel = [[UILabel alloc]init];
        timeLabel.textAlignment = UITextAlignmentCenter;
        timeLabel.font = [UIFont systemFontOfSize:30];
        timeLabel.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];
        timeLabel.textColor = [UIColor darkGrayColor];
        homeImageView = [[UIImageView alloc]init];
        awayImageView = [[UIImageView alloc]init];


        [self.contentView addSubview:homeLabel];
        [self.contentView addSubview:awayLabel];
        [self.contentView addSubview:timeLabel];
        [self.contentView addSubview:tournamentLabel];
        [self.contentView addSubview:homeImageView];
        [self.contentView addSubview:awayImageView];

    }
    return self;
}
jszumski
  • 7,430
  • 11
  • 40
  • 53
Dominic Williams
  • 1,538
  • 2
  • 13
  • 17

2 Answers2

14

You have to clear the image view if you have no image to display:

...
if (tempString!=nil) {
    cell.homeImageView.image = [UIImage imageNamed:tempString];
} else {
    cell.homeImageView.image = nil;
}
...
Ole Begemann
  • 135,006
  • 31
  • 278
  • 256
  • Thanks that worked a treat! Although I still don't understand why I have to do that when my CustomCell has no homeImageView set at init? – Dominic Williams Jan 06 '11 at 21:41
  • 7
    Because of cell reuse. `dequeueReusableCellWithIdentifier` will return a cell to you that has already been used. If it contained an image in its first use, it will still contain the same image now that it is returned to you from the reuse pool. So you have to reset all properties of the cell that might have been set in a previous cycle. – Ole Begemann Jan 06 '11 at 21:44
  • Thanks for that. I understand how the cell's are getting re-used now – Dominic Williams Jan 06 '11 at 21:52
0

Optionally, you can implement prepareForReuse:

In Swift:

override func prepareForReuse() {
    cell.homeImageView.image = nil;
}
bshirley
  • 8,217
  • 1
  • 37
  • 43