Строка не движется при изменении модели с NSFetchResultsController
Я работаю над своим первым приложением для iPhone (базовое приложение со списком дел) и только что добавил NSFetchResultsController в мое табличное представление. У меня есть 2 секции строк, и у меня нет проблем с добавлением строк, и они отсортированы по тому, является ли атрибут завершенной цели истинным - если это так, то он переходит в нижнюю секцию и вычеркивается.
И всякий раз, когда вы проводите пальцем вправо по строке в верхнем разделе, он изменяет полный атрибут цели на true и перемещает его в нижний раздел:
RegimenGoal *goal = [_fetchedResultsController objectAtIndexPath:swipedIndexPath];
goal.completed = [NSNumber numberWithBool:YES];
[context save:&error];
Вот мой код контроллера представления.
По какой-то причине это работает только для целей, которые я только что создал, но не работает для существующих целей, которые я добавил. После некоторой отладки я понял, что NSFetchedResultsChangeMove не запускается, вместо этого NSFetchedResultsChangeUpdate - всякий раз, когда я делаю это действие для существующих целей, которые не являются новыми.
Об этом я также узнал в документации Apple: "Перемещенные объекты иногда сообщаются как обновленные". И я попробовал обходное решение, перечисленное там, просто проверив, является ли завершенный атрибут истинным или нет.
И когда я это делаю, я вижу, что newIndexPath не новый - это просто старый indexPath, и это вводит меня в заблуждение... есть идеи о том, почему это происходит?
1 ответ
Произошла ошибка при создании контроллера выбранных результатов. Если вы группируете результаты по разделам, указав sectionNameKeyPath:@"completed"
, затем вы должны добавить дескриптор первой сортировки, используя тот же ключ:
NSSortDescriptor *completeSort = [[NSSortDescriptor alloc] initWithKey:@"completed" ascending:YES];
NSSortDescriptor *daySort = [[NSSortDescriptor alloc] initWithKey:@"dateCreated" ascending:YES];
[dayRequest setSortDescriptors:[NSArray arrayWithObjects:completeSort, daySort, nil]];
Еще одна проблема в tableView:cellForRowAtIndexPath:
[self configureCell:cell atIndexPath:indexPath];
[cell formatCell:indexPath.section];
Здесь вы предполагаете, что раздел 0 содержит все элементы с completed = NO
и раздел 1 содержит все элементы с completed = YES
, Но если все элементы выполнены, то есть только один раздел (раздел 0), содержащий все выполненные элементы. Таким образом, вы не можете использовать indexPath.section
в качестве аргумента formatCell
, Вы должны использовать значение goal.completed
вместо. Например, вы можете переместить formatCell
позвонить в configureCell:atIndexPath:
метод:
- (void)configureCell:(RegimenCell *)cell atIndexPath:(NSIndexPath *)indexPath {
RegimenGoal *goal = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.label.text = goal.text;
[cell formatCell:goal.completed.intValue];
}
И теперь нет смысла делать ячейку таблицы reuseIdentifier
зависит от раздела и номера строки. Я думаю, что вы можете просто заменить
NSString *CellIdentifier = [NSString stringWithFormat:@"%d-%d", indexPath.row, indexPath.section];
фиксированной строкой
NSString *CellIdentifier = @"YourCellIdentifer";
Аналогичная проблема заключается в setNavTitle
метод:
int goalsCount = [_tableView numberOfRowsInSection:0];
int completedCount = [_tableView numberOfRowsInSection:1];
Опять же, если все цели достигнуты, они все находятся в разделе 0, и в нем нет раздела 1. Ваш текущий код будет отображать "(0%)" в этом случае вместо "(100%)".
Дальнейшие замечания:
- Обходной путь "Перемещенные объекты иногда сообщается как обновленный" здесь не нужен.
- Для
NSFetchedResultsChangeUpdate
событие, вы можете позвонить либо[self configureCell:...]
или же[[_tableView reloadRowsAtIndexPaths:...]
, Звонить обоим не обязательно. - Переменная экземпляра
_fetchedResultsController
следует использовать только вfetchedResultsController
метод, который создает выбранный контроллер результатов (FRC) по требованию. Во всех других местах вы должны использоватьself.fetchedResultsController
чтобы убедиться, что FRC создан в случае необходимости.