IOS 7 beginUpdates endUpdates несовместим
Edit:
Решение для этого ответа связано с iOS7, иногда возвращающим NSIndexPath
и другими моментами возврата NSMutableIndexPath
. Проблема не была связана с begin/endUpdates
, но, надеюсь, решение поможет некоторым другим.
Все - я запускаю свое приложение на iOS 7, и у меня возникают проблемы с методами beginUpdates
и endUpdates
для UITableView
.
У меня есть табличное представление, которое нужно изменить высоту ячейки при касании. Ниже мой код:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// If our cell is selected, return double height
if([self cellIsSelected:indexPath]) {
return 117;
}
// Cell isn't selected so return single height
return 58;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
ChecklistItemCell *cell = (ChecklistItemCell *)[self.tableview cellForRowAtIndexPath:indexPath];
[cell.decreaseButton setHidden:NO];
[cell.increaseButton setHidden:NO];
// Toggle 'selected' state
BOOL isSelected = ![self cellIsSelected:indexPath];
DLog(@"%@", selectedIndexes);
DLog(@"is selected: %@", isSelected ? @"yes":@"no");
// Store cell 'selected' state keyed on indexPath
NSNumber *selectedIndex = @(isSelected);
selectedIndexes[indexPath] = selectedIndex;
[tableView beginUpdates];
[tableView endUpdates];
}
Методы beginUpdates
и endUpdates
работают довольно непоследовательно. Метод didSelectRowAtIndexPath
вызывается правильно при каждом касании (я думал, что сначала пользовательский интерфейс блокируется), а selectedIndexes
правильно сохраняет переменные значения. Проблема в том, что иногда я касаюсь ячейки таблицы, и все методы называются правильно, но высота ячейки не изменяется. Кто-нибудь знает, что происходит?
Ответы
Ответ 1
В iOS7 наблюдается изменение поведения, где пути указателей иногда являются экземплярами NSIndexPath
и других времен UIMutableIndexPath
. Проблема в том, что isEqual
между этими двумя классами всегда возвращается NO
. Таким образом, вы не можете надежно использовать указательные пути в качестве словарных клавиш или в других сценариях, которые полагаются на isEqual
.
Я могу представить пару жизнеспособных решений:
-
Напишите метод, который всегда возвращает экземпляр NSIndexPath
и использует его для генерации ключей:
- (NSIndexPath *)keyForIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath class] == [NSIndexPath class]) {
return indexPath;
}
return [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
}
-
Определите строки данными, а не путь индекса. Например, если ваша модель данных является массивом NSString
, используйте эту строку в качестве ключа в вашей карте selectedIndexes
. Если ваша модель данных представляет собой массив NSManagedObjects
, используйте objectID
и т.д.
Я успешно использую оба этих решения в своем коде.
EDIT Модифицированное решение (1) на основе предложения @rob о возврате NSIndexPaths
, а не NSStrings
.
Ответ 2
endUpdates
не следует вызывать сразу после beginUpdates
. В последней документации говорится: "Начните серию вызовов методов, которые вставляют, удаляют или выбирают строки и разделы получателя". Это говорит о том, что его следует вызывать в willSelectRowAtIndexPath:
и endUpdates
следует вызывать в didSelectRowAtIndexPath
.