Получить объект раздела NSFetchedResultsController из viewForSupplementaryElementOfKind UICollectionView
У меня есть модель данных под названием Location
. Я использую их в качестве заголовков разделов в UICollectionViewController
. Каждый location
может отображать items
внутри этих разделов. Я хочу настроить заголовки разделов в viewForSupplementaryElementOfKind
. Но я не могу понять, как получить правильные Location
объекты из этого метода.
Я пробовал такие вещи, как:
-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections] [indexPath.section];
Item *item = sectionInfo.objects[0];
Location *location = item.location;
SectionHeaderView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"SectionHeader" forIndexPath:indexPath];
headerView.label.text = location.name;
[...]
Но я продолжаю получать:
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
Это, вероятно, потому, что можно иметь местоположение без каких-либо элементов. Есть еще идеи, как мне это сделать?
1 ответ:
Ваш код выглядит вполне корректно, и он работал, как и ожидалось, в моем небольшом тестовом приложении. Поэтому я предполагаю, что у вас есть некоторая ошибка в методах источника данных.
Вот что я использовал:
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return [[self.frc sections] count]; } -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { id <NSFetchedResultsSectionInfo> sectionInfo = [self.frc sections][section]; return [sectionInfo numberOfObjects]; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { CellView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CellView" forIndexPath:indexPath]; Item *item = [self.frc objectAtIndexPath:indexPath]; cell.name.text = item.name; return cell; } -(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { id <NSFetchedResultsSectionInfo> sectionInfo = [self.frc sections][indexPath.section]; Item *item = sectionInfo.objects[0]; Location *location = item.location; HeaderView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath]; headerView.title.text = location.name; return headerView; }
Контроллер результатов выборки создается следующим образом:
- (NSFetchedResultsController *)frc { if (_frc == nil ) { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Item"]; NSSortDescriptor *sort1 = [[NSSortDescriptor alloc] initWithKey:@"location.name" ascending:NO]; NSSortDescriptor *sort2 = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO]; NSArray *sortDescriptors = @[sort1, sort2]; [fetchRequest setSortDescriptors:sortDescriptors]; _frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.context sectionNameKeyPath:@"location.name" cacheName:nil]; NSError *error; _frc.delegate = self; [_frc performFetch:&error]; } return _frc; }
Примечание: автоматическое обновление представления коллекции с помощью контроллера результатов выборки довольно хитрые, так что это статья
Http://ashfurrow.com/blog/how-to-use-nsfetchedresultscontroller-with-uicollectionview
(с примерами кода) может быть интересно.