У меня есть следующие примеры кода:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[namesArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
и
if ([nameSection count] == 0)
{
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView beginUpdates];
[indexKeys removeObjectAtIndex:section];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
Обратите внимание на порядок.... в первом примере я сначала удаляю объект из своего массива, а затем удаляю строку из таблицы.
Во втором примере я удаляю строку из таблицы, затем раздел из моего массива, затем раздел из таблицы.
Это правильный порядок действий? Или я должен сначала удалить его из пользовательского интерфейса, а затем массивы?
Причина, по которой я спрашиваю, заключается в том, что некоторые пользователи сообщают об этих сбоях, которые я не могу воспроизвести:
NSInternalInconsistencyException - недопустимое обновление: недопустимое количество строк в разделе 1. Количество строк, содержащихся в существующем разделе после обновления (0), должно быть равно количеству строк, содержащихся в этом разделе до
с этой трассировкой стека:
1: libobjc.A.dylib objc_exception_throw 32
2: CoreFoundation [NSException raise:format:] 0
3: Foundation -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] 90
4: UIKit -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] 6042
5: UIKit -[UITableView _updateRowsAtIndexPaths:updateAction:withRowAnimation:] 254
6: UIKit -[UITableView deleteRowsAtIndexPaths:withRowAnimation:] 26
7: Movies _mh_execute_header 253319
8: UIKit -[UITableView(UITableViewInternal) animateDeletionOfRowWithCell:] 84
9: CoreFoundation -[NSObject performSelector:withObject:withObject:] 52
10: UIKit -[UIApplication sendAction:to:from:forEvent:] 62
Ответ 2 · рейтинг 3 · sangony
После того, как таблица перейдет в режим редактирования, табличное представление спросит у источника данных, должна ли каждая строка быть редактируемой. Если реализован метод tableView:canEditRowAtIndexPath:, он вызывается для каждой строки по очереди.
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return NO;
}
return YES;
}
Установив, можно ли редактировать строку, табличное представление затем спрашивает делегата, какой стиль редактирования следует использовать для каждой строки:
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
При нажатии кнопки "Удалить" tableView отправляет сообщение tableView:commitEditingStyle:forRowAtIndexPath: источнику данных. Он принимает три параметра:
1) Ссылка на сам tableView (на случай, если источнику данных нужно различать несколько tableView).
2) UITableViewCellEditingStyle только что нажатого элемента управления - в данном случае UITableViewCellEditingStyleDelete
3) Объект indexPath, определяющий местонахождение рассматриваемой строки.
Когда источник данных получает сообщение commitEditingStyle:forRowAtIndexPath:, ему необходимо сделать две вещи:
1) Обновите модель tableView, удалив объект, представленный строкой в таблице. Помните, что сама таблица - это просто представление, и если мы не удалим объект из модели, он снова появится в таблице при следующей перезагрузке таблицы.
2) Отправьте сообщение tableView:deleteRowsAtIndexPath:withRowAnimation: в tableView, чтобы оно обновило отображение таблицы. В этом случае, поскольку мы имеем дело с Delete, он будет анимировать удаленную ячейку, скользящую влево, а затем перемещать ячейки под ней вверх, чтобы закрыть зазор.
-(void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.tableData removeObjectAtIndex:indexPath.row];
NSArray *indexPathArray = [NSArray arrayWithObject:indexPath];
[tableView deleteRowsAtIndexPaths:indexPathArray
withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
На выбор предлагается ряд анимаций вставки и удаления ячеек таблицы:
- UITableViewRowAnimationFade - появление и исчезновение строк.
- UITableViewRowAnimationRight - вставленные строки скользят справа; удаленные строки выдвигаются вправо.
- UITableViewRowAnimationLeft - вставленные строки скользят слева; удаленные строки выдвигаются влево.
- UITableViewRowAnimationTop - вставленные строки скользят вниз от нижней части строки выше; удаленные строки перемещаются вверх к нижней части строки выше.
- UITableViewRowAnimationBottom - вставленные строки скользят вверх от верхней части ячейки ниже; удаленные строки кажутся покрытыми строкой ниже, скользящей вверх.
- UITableViewRowAnimationNone - просто появляются вставленные строки; удаленные строки просто исчезают.
- UITableViewRowAnimationMiddle - ячейки вставляются и удаляются с эффектом аккордеона.
- UITableViewRowAnimationAutomatic - tableView автоматически выбирает подходящий стиль анимации (доступен только в iOS 5 и более поздних версиях).
Отличная книга о том, как работать с таблицами, находится здесь.