NSFetchedResultsController - порядок сортировки, отличный от названия раздела
У меня есть NSManagedObject для разделов в сгруппированном UITableView.
Этот объект имеет атрибуты "имя" и "createdAt".
Я хочу использовать "имя" в пользовательском интерфейсе для заголовков разделов, но отсортировано по "createdAt".
Согласно документации, первым ключом sortDescriptor должен быть также sectionNameKeyPath из NSFetchedResultsController.
Я предложил использовать два sortDescriptors, но он не работает. Разделы по-прежнему сортируются по имени.
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:[CoreDataHelper instance].managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortName = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSSortDescriptor *sortDate = [[NSSortDescriptor alloc] initWithKey:@"createdAt" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortName, sortDate, nil]];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:[CoreDataHelper instance].managedObjectContext sectionNameKeyPath:@"name"
cacheName:@"Root"];
self.fetchedResultsController = theFetchedResultsController;
return _fetchedResultsController;
}
Ответы
Ответ 1
Приведенный контроллер результатов (FRC) использует только первый дескриптор сортировки для группировки (и сортировки) объектов в разделы. Второй сортировочный дескриптор может быть добавлен для сортировки объектов в каждом разделе.
Кроме того, путь ключа дескриптора сортировки должен быть таким же, как и sectionNameKeyPath
FRC (или, по крайней мере, генерировать то же относительное упорядочение).
В вашем случае вы можете действовать следующим образом:
- Используйте
createdAt
как sectionNameKeyPath
и в первом дескрипторе сортировки.
-
Измените функцию делегата titleForHeaderInSection
, чтобы вернуть свойство name
вместо createdAt
:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.controller sections] objectAtIndex:section];
return [[[sectionInfo objects] objectAtIndex:0] name];
}
Примечание. Если у вас есть несколько объектов с одинаковыми значениями name
, но с разными значениями createAt
, они будут сгруппированы в разные разделы с помощью вышеуказанного подхода. Я не знаю, если это проблема для вас.
Ответ 2
Ты почти там. Вам необходимо определить sectionNameKeypath в вызове initWithFetchRequest.
NSSortDescriptor *sortDate = [[NSSortDescriptor alloc] initWithKey:@"createdAt" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDate]];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[CoreDataHelper instance] sectionNameKeyPath:@"name"];