Заставить UITableView сбросить все повторно используемые ячейки - PullRequest
5 голосов
/ 07 июля 2010

У меня есть UITableView, в котором цвет фона задан через

UIView *myView = [[UIView alloc] init];
if ((indexPath.row % 2) == 0)
    myView.backgroundColor = [UIColor greenColor];
else
    myView.backgroundColor = [UIColor whiteColor];

cell.backgroundView = myView;
[myView release];

Проблема, которую я нахожу, заключается в том, что при редактировании таблицы (через setEditing: YES ...) некоторые ячейки одного цветаНеизменные находятся рядом друг с другом.Как заставить UITableView полностью перерисовать.reloadData не делает большую работу.

Есть ли глубокая очистка?

Ответы [ 5 ]

4 голосов
/ 07 июля 2010

У меня была эта проблема раньше, поэтому я поделюсь с вами тем, как я ее решил:

Вы можете использовать логический флаг (скажем, он называется needsRefresh), чтобы управлять поведением создания ячейки в -cellForRowAtIndexPath:

Пример:

- (UITableViewCell*) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath {
    UITableViewCell *cell = [tableView dequeueResuableCellWithIdentifier:SOME_ID];
    if(!cell || needsRefresh) {
       cell = [[[UITableViewCell alloc] init....] autorelease];
    }
    //.....
    return cell;
}

Так что, когда вам нужна перезагрузка, установите флаг needsRefresh на YES.Просто как прыщик.

3 голосов
/ 30 ноября 2012

Для меня принятый ответ на самом деле не сработал, так как я понятия не имел, когда для установки needsRefresh обратно на YES.

Что сработало для меня:

 - (UITableViewCell*) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath {
    UITableViewCell *cell = [tableView dequeueResuableCellWithIdentifier:customCellIdentifier];
    if(nil == cell) {
        cell = [[UITableViewCell alloc]  initWithStyle:UITableViewCellStyleDefault
                                       reuseIdentifier:customCellIdentifier];
    }
    //.....
    return cell;
}

И затем вы меняете значение customCellIdentifier, когда вам это необходимо. Таким образом, ячейки также можно использовать повторно, если вы вернетесь к исходному идентификатору ячейки.

1 голос
/ 18 сентября 2014

Принятый метод кажется грязным, он просто создает кучу новых ячеек, которые хранятся вместе с плохими. Вот несколько решений в зависимости от вашей ситуации:

1. Во-первых, для ситуации, описанной в вопросе, вы не должны сбрасывать свои ячейки и создавать новые представления для каждого цикла. Вам нужно пометить свой вид, а затем получить его обратно из ячейки, когда вы получите ячейку повторного использования:

- (UITableViewCell*) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath {
    UITableViewCell *cell = [tableView dequeueResuableCellWithIdentifier:SOME_ID];
    if(!cell) {
       cell = [[UITableViewCell alloc] init];

         UIView *myView = [[UIView alloc] init];    
        cell.backgroundView = myView;

        [myView setTag:5]; //<------
    }

    UIView *myView =  [cell viewWithTag:5];  //<------
    if ((indexPath.row % 2) == 0)
        myView.backgroundColor = [UIColor greenColor];
    else
        myView.backgroundColor = [UIColor whiteColor];
    return cell;
}

//then just reload the tableview.

2. ... или, что еще лучше, почему бы просто не использовать цвет фона ячейки и не обновлять его, не создавая представление.

3. Верный способ действительно очистить старые кэшированные ячейки, просто воссоздать объект UITableView.

4. В большинстве случаев вам не нужно уничтожать эти ячейки, просто следите за вашими элементами и обновляйте их после получения многократно используемой ячейки. Вы можете пометить все свои элементы, сохранить ссылку на них массива, найти их с учетом иерархии представления ... Im конечно, есть множество других способов.

5. Вот один вкладыш для прямой очистки всех ячеек, хотя не рекомендуется возиться с внутренностями таких объектов, как они могут измениться в будущих версиях:

[(NSMutableDictionary*)[tableview valueForKey:@"_reusableTableCells" ] removeAllObjects];
0 голосов
/ 11 августа 2014
#define TABLE_VIEW_CELL_DEFAULT_ID @"cellIdentifier"
@property (nonatomic, strong) NSString *tableViewCellIdentifier;
@property (nonatomic) NSUInteger tableViewCellIdentifierCount;

// By using a different cell identifier, this effectively flushes the cell 
// cache because the old cells will no longer be used.
- (void) flushTableViewCellCache
{
    self.tableViewCellIdentifierCount++;
    self.tableViewCellIdentifier = [NSString stringWithFormat:@"%@%i", TABLE_VIEW_CELL_DEFAULT_ID, self.tableViewCellIdentifierCount];
}

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

    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.tableViewCellIdentifier];
    if (cell == nil) {
        cell = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:self.tableViewCellIdentifier];
    }

    // rest of method...
}
0 голосов
/ 08 августа 2014

Мне удалось решить эту проблему, добавив переменную обновления в источник данных таблицы.Я использовал словарь для каждой ячейки, но есть дополнительный ключ, который называется @ "refresh": @ "1", что указывает на необходимость обновления ячейкиПосле обновления я установил значение этого ключа на @ "0".Поэтому, когда таблица перезагружается, убедитесь, что ключ снова возвращается к @ "0".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...