iOS Reusing Cells in Table View Problem

newtoiphonesdk

macrumors 6502a
Original poster
Jul 30, 2010
567
2
Having issues with Cell setup in a TableView...I set up table view with an image view, and two labels, one title, and one details. First part looks fine, but after scrolling, it continually piles all the labels on top of each other.

Here is my code:

Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        
    }
    
    
    
    RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
       NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
    [dateFormatter setTimeStyle:NSDateFormatterShortStyle];
    [dateFormatter setDateStyle:NSDateFormatterShortStyle];
    NSString *articleDateString = [dateFormatter stringFromDate:entry.articleDate];
    NSLog(@"%@", articleDateString);
    //  cell.textLabel.text = entry.articleTitle; 
    // cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ - %@", articleDateString, entry.blogTitle];
    
	UIFont *cellFont = [UIFont fontWithName:@"ArialRoundedMTBold" size:17];    
    //cell.textLabel.font = cellFont;
    UIFont *cellFont2 = [UIFont fontWithName:@"ArialRoundedMTBold" size:12];    
    //cell.detailTextLabel.font = cellFont2;
    UIImage *img = [UIImage imageNamed:@"anicon.png"];
    UIImageView *alternate = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,70,70)];
    
    
    alternate.image = img;
    UILabel *alternatelabel = [[UILabel alloc] initWithFrame:CGRectMake(75,0,210,70)];
    alternatelabel.backgroundColor = [UIColor clearColor];
    UILabel *detailLabel = [[UILabel alloc] initWithFrame:CGRectMake(75, 20, 225, 70)];
    detailLabel.backgroundColor = [UIColor clearColor];
    detailLabel.text = [NSString stringWithFormat:@"%@ - %@", articleDateString, entry.blogTitle];
    detailLabel.font = cellFont2;
    alternatelabel.font = cellFont;
    
    alternatelabel.text = entry.articleTitle;
    
    [cell.contentView addSubview:alternate];
    [cell.contentView addSubview:alternatelabel];
    [cell.contentView addSubview:detailLabel];
    [detailLabel release];
    [alternatelabel release];
    [alternate release];
    NSLog(@"imageurl%@", img);
    
    return cell;
}
 

Ides

macrumors member
Mar 27, 2012
95
0
TableViewCellReusing

The problem is that UITableViewCells are reused, and each time you set one up you add a new label to its view which doesn't ever get taken away. As far as I can see, there's two solutions:

The first is, in the beginning of your method add the following line of code:
Code:
 [cell.subviews makeObjectsPerformSelector:@selector(removeFromSuperView)];
That should get rid of your excess labels, but might also get rid of the detail text label.

Another solution, though it takes more work, will make your code a bit cleaner. Make a subclass of UITableViewCell, and give it instance variables & properties for the labels that you want it to have, so that the labels can be reused along with the cell.
 
Comment

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
Look at some of Apple's UITableView sample code. Or look at absolutely any example code ever written to demonstrate how to use UITableView. This is one of the most fundamental features of UITableView.

@Ides,
Code:
makeObjectsPerformSelector:@selector(removeFromSuperView)
Ha Ha. Very funny :)
 
Comment

MattInOz

macrumors 68030
Jan 19, 2006
2,761
0
Sydney
The problem is that UITableViewCells are reused, and each time you set one up you add a new label to its view which doesn't ever get taken away. As far as I can see, there's two solutions:

The first is, in the beginning of your method add the following line of code:
Code:
 [cell.subviews makeObjectsPerformSelector:@selector(removeFromSuperView)];
That should get rid of your excess labels, but might also get rid of the detail text label.

Another solution, though it takes more work, will make your code a bit cleaner. Make a subclass of UITableViewCell, and give it instance variables & properties for the labels that you want it to have, so that the labels can be reused along with the cell.
Yep,
don't be afraid of UITableViewCell sub-classes, really looks like it time to learn about them.

I'd suggest pull back the code make it work first with one of UITableViewCell presentations.
 
Comment

Ides

macrumors member
Mar 27, 2012
95
0
Confused

@PhonyDeveloper

Wait, why is my code funny? I use that all the time if I want a UIView totally cleared of subviews, for whatever reason.
 
Comment

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
The simple solution, and the normal way to do this, is to only add the subviews one time. If you move the code that adds the subviews inside the braces where the table view cell is built then that code will run only one time. Removing all the subviews and then adding exactly the same subviews again doesn't make sense. Using a nib or a table view cell subclass to solve this problem is also fine.

In the case where an existing cell is dequeued then all your code needs to do is set all the properties on the cell. There's no need to create any new subviews.
 
Comment

cMacSW

macrumors regular
Mar 20, 2006
180
0
PhoneyDeveloper is correct, move code for creating subviews to be called only when the cell is created, and code for updating the values should be run each time a cell is updated.
 
Comment

Similar threads

  • theprizerevealed
4
Replies
4
Views
1K
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.