Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

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;
}
 
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.
 
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 :)
 
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.
 
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.
 
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.
 
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.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.