Повторное использование TableView Cell и нежелательные галочки - это убивает меня - PullRequest
11 голосов
/ 11 июня 2011


iOS от Apple TableView и повторное использование сотовой связи убивает меня.Я искал, искал и учился, но не могу найти хорошие документы или хорошие ответы.Проблема заключается в том, что когда TableView повторно использует ячейки, такие вещи, как «Галочки» (принадлежность ячейки), установленные в выбранной ячейке, повторяются в ячейках, расположенных ниже в табличном представлении.Я понимаю, что повторное использование ячеек происходит из-за ограничений памяти, но если у вас есть список, скажем, с 50 элементами, и он начинает устанавливать дополнительные галочки там, где они не нужны, это делает все усилия бесполезными.

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

У Apple даже есть пример проекта TouchCell, который можно загрузить сЦентр разработки, который должен показывать другой способ установки галочки с помощью пользовательской ячейки с элементом управления изображением слева.Проект использует объект словаря для источника данных вместо изменяемого массива, поэтому для каждого элемента есть строковое значение и проверенное значение bool.Предполагается, что это проверенное значение bool устанавливает галочку, чтобы можно было отслеживать выбранные элементы.Этот пример проекта также отображает это глупое поведение, как только вы заполните TableView 15+ ячейками.Повторное использование ячеек начинает устанавливать нежелательные галочки.

Я даже пытался экспериментировать с использованием действительно уникального идентификатора ячейки для каждой ячейки.Поэтому вместо того, чтобы в каждой ячейке было что-то вроде @ "Acell", я использовал статическое int, приводил к строке, чтобы ячейки получали @ "cell1", @ "cell2" и т. Д. Во время тестирования я мог видеть, что сотни новыхгенерируется при прокрутке, даже если в таблице было только 30 элементов.

Исправлена ​​проблема с повторением галочки, но я подозреваю, что использование памяти слишком велико.

Как будто создаются ячейки, которые в данный момент не находятся в видимой области таблицыснова и снова, когда они прокручиваются обратно в поле зрения.

Кто-нибудь придумал элегантное решение этого раздражающего поведения?

1 Ответ

17 голосов
/ 11 июня 2011

повторное использование ячейки может быть сложным, но вы должны иметь в виду 2 вещи:

  • Использование один идентификатор для одного типа ячейки - Использование несколькихидентификаторы действительно нужны только тогда, когда вы используете разные подклассы UITableViewCell в одном табличном представлении, и вы должны полагаться на их различное поведение для разных ячеек
  • Повторно используемая ячейка может находиться в любое состояние Это означает, что вам нужно снова настроить каждый аспект ячейки - особенно checkmars / images / text / accessoryViews / accessoryTypes и другие

Что вам нужно сделать, это создать хранилище для ваших состояний галочки -простой массив, содержащий bools (или NSArray, содержащий логические объекты NSNumber соответственно), должен это делать.Затем, когда вам нужно создать / повторно использовать ячейку, используйте следующую логику:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *reuseIdentifier = @"MyCellType";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    if(cell == nil) {
        /* create cell here */
    }
    // Configure cell now
    cell.textLabel.text = @"Cell text"; // load from datasource
    if([[stateArray objectAtIndex:indexPath.row] boolValue]) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
    return cell;
}

, тогда вам придется реагировать на нажатия:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [stateArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:![[stateArray objectAtIndex:indexPath.row] boolValue]]];
    [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}

Просто не забудьте использовать NSMutableArray дляхранилище данных;)

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