Сбой UITableView при обновлении ячеек, которые изменяют разделы - PullRequest
0 голосов
/ 13 января 2010

У меня есть таблица, которая отображает данные из одного массива и организует элементы в отдельные секции на основе набора фильтров. Каждый фильтр имеет соответствующий раздел. Мой пользовательский интерфейс позволяет пользователю установить флажок, встроенный в каждую ячейку таблицы. Этот флажок устанавливает флажок «флажок», который влияет на то, к какому разделу фильтруется элемент. Вот пример:

  • Раздел 1
    • Элемент A
    • Элемент B
  • Раздел 2
  • Раздел "Готово"

Если установить флажок рядом с элементом A, таблица должна измениться следующим образом:

  • Раздел 1
    • Товар B
  • Раздел 2
  • Раздел "Готово"
    • Элемент A

Ниже приведен мой код для ответа на нажатие флажка. Он выясняет, к какой строке принадлежит флажок, а затем пытается создать анимационный блок, который удаляет строку из его старого раздела и добавляет строку в конец раздела «Готово». Помните, что массив на самом деле не меняется - способ фильтрации данных в разделах изменяется в зависимости от значения проверенных свойств элементов.

- (IBAction)checkBoxTapped:(id)sender
{
 // Get the table cell
 CheckBoxControl* checkBox = (CheckBoxControl*)sender;

 UITableViewCell* cell = (UITableViewCell*)[[sender superview] superview];
 UITableView* table = (UITableView*)[cell superview];
 NSIndexPath* indexPath = [table indexPathForCell:cell];

 Item* item = [self itemAtRow:[indexPath row] inSection:[indexPath section]];
 item.checked = checkBox.checked;

 Filter* filter = [filters objectAtIndex:DONE_INDEX];
 // We want the new row at the bottom of the "Done" section.
 NSIndexPath* newIndexPath = [NSIndexPath indexPathForRow:[self countItemsWithFilter:filter] inSection:DONE_INDEX];

 [table beginUpdates];
 [table insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
 [table deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
 [table endUpdates];
}

Этот код всегда выдает исключение:

2010-01-13 00:19:44.802 MyApp[19923:207] *** Terminating app due to uncaught
exception 'NSRangeException', reason:
'*** -[NSMutableIndexSet addIndexesInRange:]:Range {2147483647, 1}
exceeds maximum index value of NSNotFound - 1'

Может кто-нибудь помочь мне выяснить, что вызывает исключение NSRangeException? Вот мой стек:

___TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION___
obj_exception_throw
+[NSException raise:format:arguments:]
+[NSException raise:format:]
-[NSMutableIndexSet addIndexesInRange:]
-[NSMutableIndexSet addIndex:]
-[_UITableViewUpdateSupport(Private) _computeRowUpdates]
-[_UITableViewUpdateSupport initWithTableView:updateItems:oldRowData:oldRowRange:newRowRange:context:]
-[UITableView(_UITableViewPrivate) _updateWithItems:withOldRowData:oldRowRange:newRowRange:context:]
-[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:]
-[UITableView endUpdates]
-[RootViewController checkBoxTapped:]

Если этот код просто неверен, то как мне анимировать удаление строки из одного раздела и добавление ее в другой?

Заранее благодарим за любую помощь, которую вы можете оказать мне.

-Mike-

Ответы [ 2 ]

1 голос
/ 15 января 2010

Хорошо, думаю, я нашел лучший подход. Вместо того, чтобы пытаться заполнить разделы с помощью функции фильтрации, я решил создать массив для каждого раздела. Массив каждого раздела содержит индексы в массив источника данных. Это выглядит примерно так:

NSArray* data = [[NSArray alloc] initWithObjects:@"Apple", @"Banana", @"Cat", @"Dog", nil]];
NSMutableArray* doneFilter = [[NSMutableArray alloc] init];
NSMutableArray* othersFilter = [[NSMutableArray alloc] initWithObjects:[NSNumber numberWithInt:0],
                                [NSNumber numberWithInt:1], [NSNumber numberWithInt:2],
                                [NSNumber numberWithInt:3], nil];

Теперь, когда пользователь нажимает флажок, я удаляю индекс элемента из othersFilter и добавляю его в конец doneFilter. Затем я удаляю и добавляю соответствующие строки в табличное представление. Это кажется намного более стабильным, чем у меня (без исключений!), И имеет дополнительное преимущество, позволяя фильтрам иметь собственный порядок.

0 голосов
/ 13 января 2010

Вызывая -insertRowsAtIndexPaths и -deleteRowsAtIndexPaths, вы только говорите UITableView обновить соответствующие строки с анимацией. Таким образом, возможная проблема заключается в том, что вам также следует обновить источник данных в соответствии с вашими изменениями (например, -numberOfRowsInSection должен возвращать фактические значения и т. Д.)

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