views:

674

answers:

1

I've got a custom UITableViewCell implementation (leveraging labels as subviews) that is rendering the list of items correctly, but when I scroll down and select an item (say number 43 of 100), I see a rendering of a cell from earlier in the list (from say, number 3 on the first render page in the table) appear on top of the cell I selected.

Here is my method:

    - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }
    // index of table view correlates to index of array
    Card *card = [cards objectAtIndex:indexPath.row];

    UILabel *cardNameLbl = [[[UILabel alloc] initWithFrame:CGRectMake(10.0, 3.0, 200.0, 18.0)] autorelease];
    cardNameLbl.tag = CARD_NAME_TAG; 
    cardNameLbl.text = card.name;
    cardNameLbl.font = [UIFont systemFontOfSize:12.0];
    cardNameLbl.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight;
    [cell.contentView addSubview:cardNameLbl];

    UILabel *cardNumLbl = [[[UILabel alloc] initWithFrame:CGRectMake(10.0, 21.0, 100.0, 18.0)] autorelease]; 
    cardNumLbl.tag = CARD_NUM_TAG;
    cardNumLbl.text = card.number;
    cardNumLbl.font = [UIFont systemFontOfSize:12.0];
    cardNumLbl.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight; 
    [cell.contentView addSubview:cardNumLbl];

    UILabel *cardTypeLbl = [[[UILabel alloc] initWithFrame:CGRectMake(110.0, 21.0, 200.0, 18.0)] autorelease]; 
    cardTypeLbl.tag = CARD_TYPE_TAG;
    cardTypeLbl.text = card.type;
    cardTypeLbl.font = [UIFont systemFontOfSize:12.0];
    cardTypeLbl.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight; 
    [cell.contentView addSubview:cardTypeLbl];

    UILabel *cardQuantityLbl = [[[UILabel alloc] initWithFrame:CGRectMake(250.0, 3.0, 50.0, 18.0)] autorelease]; 
    cardQuantityLbl.tag = CARD_QUANTITY_TAG;
    cardQuantityLbl.text = [NSString stringWithFormat:@"%d", card.have];
    cardQuantityLbl.font = [UIFont systemFontOfSize:12.0];
    cardQuantityLbl.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight;
    [cell.contentView addSubview:cardQuantityLbl];

    return cell;
}
+2  A: 

Generally, these kinds of errors (seeing data from one row in another) indicates that you're not setting the parts of your reusable cells, so it's just using old data, but I can't find any part that isn't being reset.

One thing that you should definitely do however, and that might actually fix this problem, is subclass UITableViewCell, which maintains those labels as ivars. Then you can initialize the labels and add them as subviews once, in the init method, or wherever else you choose.

What's currently happening is: each time you grab a reusable cell, it potentially already has those labels on it from before, and you're just piling more subviews on top of subviews. (Unless I'm mistaken and a reusable cell has its subviews cleared out before it is returned.)

craig
Yeah, I think you are correct about the Cell retaining the old data ... I just find it strange that this is trigger on a cell selection. Do you know what methods are triggered when select is called that would trigger a re-render? I don't think tableView:didSelectRowAtIndexPath: is doing it.
Greg
In the UITableViewCell class, there's a method called:- (void)setSelected:(BOOL)selected animated:(BOOL)animatedBut I don't know why that would be causing the subviews to become mis-ordered.
craig
I implemented a subclass of UITableViewCell and I no longer get this behavior. Strange...would like to still figure this out.
Greg
Yea, it definitely sounds like a bug of some kind. What version of the SDK are you working with?
craig
My active SDK for this project is the Simulator - iPhone OS 2.2.
Greg