UITableViewCell-как сбросить содержимое перед повторным использованием

есть раздражающая ошибка, которую я не могу исправить.

у меня есть CustomCell, и в нем у меня есть подвидение, которое изменяет его цвет в соответствии со значением объекта.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"CustomCell";

    CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    if (cell == nil) {        
        cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }

    MyObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];

    if ([object.redColor isEqualToNumber:[NSNumber numberWithBool:YES]]) {
        cell.colorView.backgroundColor = [UIColor redColor];
    }
    else {
        cell.colorView.backgroundColor = [UIColor clearColor];
    }       

    return cell;
}

это все работает нормально, за исключением случаев, когда я удаляю строку с redColor = YES из tableview, и я прокручиваю, чтобы показать строки, которые не были видны. Первые строки, проступившие (первый ряд, который использует многоразовые ячейки) имеет красный цвет, хотя эта строка redColor = NO. И если я прокручу еще раз и спрячу ячейку и затем покажите его снова, цвет установлен в clearColor, как и должно быть.

Я думаю, это потому, что он повторно использует ячейку, которая только что была удалена. Поэтому я пытаюсь сбросить содержимое ячейки перед повторным использованием. В CustomCell.m

- (void)prepareForReuse {
    [super prepareForReuse];

    self.clearsContextBeforeDrawing = YES;
    self.contentView.clearsContextBeforeDrawing = YES;
    self.colorView.backgroundColor = [UIColor clearColor];
}

но это не работает. Apple Doc говорит

делегат табличного представления в tableView: cellForRowAtIndexPath: всегда должен сбрасывать все содержимое при повторном использовании ячейки.

каков правильный способ сбросить содержимое? Нужно ли удалять подвиды из супервизора?

спасибо заранее

4 ответов


Это, кажется, работает.

Я удаляю contentView ячейки, когда prepareForReuse в CustomCell.m

- (void)prepareForReuse {
    [super prepareForReuse];

    // Clear contentView
    BOOL hasContentView = [self.subviews containsObject:self.contentView];    
    if (hasContentView) {
        [self.contentView removeFromSuperview];
    }
}

добавить его снова в cellForRowAtIndexPath

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // Cell
    static NSString *cellIdentifier = @"CustomCell";

    CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    if (cell == nil) {        
        cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }

    // Restore contentView
    BOOL hasContentView = [cell.subviews containsObject:cell.contentView];
    if (!hasContentView) {
        [cell addSubview:cell.contentView];
    }

    // Configure cell
    MyObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];

    if ([object.redColor isEqualToNumber:[NSNumber numberWithBool:YES]]) {
        cell.colorView.backgroundColor = [UIColor redColor];
    }
    else {
        cell.colorView.backgroundColor = [UIColor clearColor];
    }       

    return cell;
}

надеюсь, что это поможет кому-то.


вы можете использовать этот метод делегата tableview для изменения видимости (например, цвета фона), но не данных:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

        - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
        {
            NSString *cellIdentifier = [NSString stringWithFormat:@"CustomCell %ld",(long)indexPath.row];


            CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
            cell = nil;

            if (cell == nil)
            {
                cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];


                MyObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];

                if ([object.redColor isEqualToNumber:[NSNumber numberWithBool:YES]]) 
                {
                    cell.colorView.backgroundColor = [UIColor redColor];
                }
                else
                {
                    cell.colorView.backgroundColor = [UIColor clearColor];
                }


            return cell;
        }

Если вы хотите удалить все ячейки из списка ячеек повторного использования, используйте:

[tblView setValue:nil forKey:@"_reusableTableCells"]

Если вы хотите удалить одну ячейку из списка ячеек повторного использования, используйте:

NSString* cellID = [NSString stringWithFormat:@"cellID%ld%ld",(long)indexPath.section,(long)indexPath.row];
        NSMutableDictionary *temp1 = (NSMutableDictionary*)[tblView valueForKey:@"_reusableTableCells"];
        [temp1 removeObjectForKey:cellID];
        [tblView setValue:temp1 forKey:@"_reusableTableCells"];

где cellID-уникальный идентификатор ячейки повторного использования при инициализации ячейки.