3

У меня есть модель данных с именем Location. Я использую их в качестве заголовков разделов в UICollectionViewController. Каждый location может отображать items внутри этих разделов. Я хочу настроить заголовки разделов в viewForSupplementaryElementOfKind. Но я не могу понять, как извлечь из этого метода правильные объекты Location.Получить объект раздела NSFetchedResultsController из представления UICollectionView forSupplementaryElementOfKind

Я пытался что-то вроде:

-(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' 

Это, вероятно, потому, что это возможно, чтобы иметь место без каких-либо предметов. Любые другие идеи о том, как я должен это делать?

+0

Возникает ли проблема только для разделов без предметов? Другими словами, вы получаете правильные объекты местоположения, если все разделы не пусты? –

+0

Нет, но я не уверен, как получить правильные местоположения, если у него нет никаких элементов, и я не могу сделать 'item.location'. – Anders

+0

На самом деле мне интересно, как вы получаете разделы с нулевыми элементами вообще, при использовании настройки, как в ответе на ваш предыдущий вопрос. В ваших источниках данных или делегировании могут возникнуть проблемы. Но я не уверен ... –

ответ

3

Ваш код выглядит совершенно правильно, и он работал, как ожидалось, в моем маленьком тестовом приложении. Поэтому я предполагаю, что у вас есть некоторая ошибка в методах источника данных.

Это то, что я использовал:

-(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; 
} 

Примечания: The автоматических обновления из представления коллекции с микросхемой принесенными результатов контроллер довольно сложный, поэтому эта статья

http://ashfurrow.com/blog/how-to-use-nsfetchedresultscontroller-with-uicollectionview

(с примерами кода) может быть интересным.

+0

Спасибо, но это также означает, что каждый раздел/местоположение должен иметь хотя бы один элемент? Выглядит очень похоже на то, что у меня есть сейчас. Что вы думаете о: https://github.com/timothyarmes/TAFetchedResultsController? – Anders

+0

@Anders: Мой ответ относится к «нормальному» FRC, который (насколько я знаю) не может иметь пустые разделы. Я не знал, что вы используете «специальный» FRC. Я посмотрю на этот проект, но, вероятно, не раньше завтра. –

+0

Хорошо, хорошо. Я еще не использую его. Но думать об этом. Дайте мне знать, что вы думаете! :) – Anders

Смежные вопросы