Повторное использование ячейки TableView и нежелательные галочки - это убивает меня
Apple iOS TableView
и повторное использование ячеек убивают меня. Я искал, искал и учился, но не могу найти хорошие документы или хорошие ответы. Проблема заключается в том, что при повторном использовании элементов TableView
в ячейках, расположенных дальше в представлении таблицы, повторяются элементы, такие как контрольные метки (принадлежность ячейки), установленные в выбранной ячейке. Я понимаю, что повторное использование ячеек по дизайну из-за ограничений памяти, но если у вас есть список с 50 наименованиями, и он начинает устанавливать дополнительные галочки, где они не нужны, это делает все усилия бесполезными.
Все, что я хочу сделать, это установить галочку на ячейке, которую я выбрал. Я пробовал это, используя свой собственный класс ячеек, и стандартные ячейки, сгенерированные классом TableView для плиты котла, но он всегда заканчивается тем же.
У Apple даже есть пример проекта TouchCell, который вы можете загрузить из центра dev, который должен показать другой способ установки галочки с помощью пользовательской ячейки с элементом управления изображением слева. В проекте используется объект словаря для источника данных вместо muteable array, поэтому для каждого элемента есть строковое значение и значение bool checked. Это проверенное значение bool должно установить галочку, чтобы отслеживать выбранные элементы. Этот примерный проект также отображает это дурацкое поведение, как только вы заполняете TableView с помощью 15+ ячеек. Повторное использование ячеек начинает устанавливать нежелательные отметки.
Я даже попытался поэкспериментировать с использованием подлинно уникального Cell Identifier для каждой ячейки. Поэтому вместо каждой ячейки, имеющей что-то вроде @ "Acell", я использовал статический int, отбрасываемый в строку, поэтому ячейки получили @ "cell1", @ "cell2" и т.д. Во время тестирования я мог видеть, что сотни новых ячеек, созданный во время прокрутки, даже если в таблице было всего 30 элементов.
Он исправил проблему с повторением галочки, но я подозреваю, что использование памяти слишком сильно.
Как будто ячейки, которые в настоящее время не отображаются в области видимости таблицы, создаются снова, когда они прокручиваются назад.
Кто-нибудь придумал элегантное решение этого раздражающего поведения?
Ответы
Ответ 1
Повторное использование ячеек может быть сложным, но вы должны учитывать 2 вещи:
- Использовать один идентификатор для одного типа ячейки. Использование нескольких идентификаторов действительно необходимо только при использовании разных подклассов UITableViewCell в одном представлении таблицы, и вам приходится полагаться на их различное поведение для разных ячеек
- Ячейка, которую вы повторно используете, может находиться в состоянии, что означает, что вам нужно снова настроить каждый аспект ячейки - особенно checkmars/images/text/accessoriesViews/accessoriesTypes и многое другое
Что вам нужно сделать, так это создать хранилище для ваших состояний галочки - это простой массив, содержащий 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
для вашего хранилища данных;)