user440096
user440096

Reputation:

How do I clear a cell completely when I reuse it?

When I call [table reloaddata];

The cells get redrawn with new data, but my UILabels get messed up because they are drawn over the old UILabels, so its a mess.

    static NSString* PlaceholderCellIdentifier = @"PlaceholderCell";

UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];


if (cell == nil)
{
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:PlaceholderCellIdentifier] autorelease];   
    cell.detailTextLabel.textAlignment = UITextAlignmentCenter;
    cell.selectionStyle = UITableViewCellSelectionStyleNone;


    cell.contentView.backgroundColor = [UIColor clearColor];
}

Is my Init of the cell.

I add a UILabel like so

        UILabel *theDateLabel = [[UILabel alloc] initWithFrame:CGRectMake(140, 35,140, 20)];
    [theDateLabel setBackgroundColor:[UIColor clearColor]];
    [theDateLabel setTextColor:[UIColor lightGrayColor]];
    [theDateLabel setText:[dateFormatter stringFromDate:theDate]];
    [theDateLabel setFont:[UIFont fontWithName:@"TrebuchetMS-Bold" size:15]];
    [cell addSubview:theDateLabel];
    [theDateLabel release];

There are a few more labels in the cell, same thing.

What I would like to happen is that the old labels disappear from the cell so that they are no longer visible.

Upvotes: 1

Views: 8398

Answers (2)

rob mayoff
rob mayoff

Reputation: 385650

You should not add theDateLabel as a subview of cell. You should add it as a subview of cell.contentView.

As yuji suggests, one way to implement this is to create a subclass of UITableViewCell with a property for each custom subview. That way you can easily get to the date label of a reused cell to set its text for the new row.

Another common approach is to use the tag property that every UIView has. For example:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString* PlaceholderCellIdentifier = @"PlaceholderCell";
    static const int DateLabelTag = 1;

    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
    if (!cell) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:PlaceholderCellIdentifier] autorelease];   

        UILabel *theDateLabel = [[UILabel alloc] initWithFrame:CGRectMake(140, 35,140, 20)];
        theDateLabel.tag = DateLabelTag;
        theDateLabel.backgroundColor = [UIColor clearColor];
        theDateLabel.textColor = [UIColor lightGrayColor];
        theDateLabel.font = [UIFont fontWithName:@"TrebuchetMS-Bold" size:15];
        [cell.contentView addSubview:theDateLabel];
        [theDateLabel release];
    }

    NSDate *theDate = [self dateForRowAtIndexPath:indexPath];
    UILabel *theDateLabel = [cell.contentView viewWithTag:DateLabelTag];
    theDateLabel.text = [dateFormatter stringFromDate:theDate];

    return cell;
}

Upvotes: 10

yuji
yuji

Reputation: 16725

While Richard's solution will work, if your cells have any other subviews they'll get removed as well. Also, allocating and initializing your subviews every time you draw a cell isn't necessarily optimal.

The standard solution here is to create a subclass of UITableViewCell with a property @dateLabel (and so on for the other labels). Then, when you're initializing a cell, if it doesn't have a @dateLabel yet you can give it a new one, otherwise you only have to set its text.

Upvotes: 5

Related Questions