Reusing Cells in Table View Problem

Discussion in 'iOS Programming' started by newtoiphonesdk, Jun 13, 2012.

  1. newtoiphonesdk macrumors 6502a

    Joined:
    Jul 30, 2010
    #1
    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;
    }
    
     
  2. Ides macrumors member

    Joined:
    Mar 27, 2012
    #2
    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.
     
  3. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #3
    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 :)
     
  4. MattInOz macrumors 68030

    MattInOz

    Joined:
    Jan 19, 2006
    Location:
    Sydney
    #4
    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.
     
  5. Ides macrumors member

    Joined:
    Mar 27, 2012
    #5
    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.
     
  6. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #6
    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.
     
  7. cMacSW macrumors regular

    Joined:
    Mar 20, 2006
    #7
    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.
     

Share This Page