Подтвердить что ты не робот

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;
}
4b9b3361

Ответ 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"];