修复了UICollectionView中的静态单元格

时间:2014-10-23 10:05:32

标签: ios objective-c uicollectionview

https://puu.sh/cnc93/70bd9c423f.png

在我的iPad应用程序中,我使用了一个UICollectionView,它通过NSFetchedResultsController显示用户在核心数据中保存的不同注释。 根据设计,我必须显示一个带有控件的单元格,以在核心数据中添加新笔记。添加注释后,它将显示为集合视图中的第二个单元格。

我试图以下面的方式实现它;

#pragma mark - UICollectionViewDataSource

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView*)collectionView
{
    return self.fetchedResultsController.sections.count?:1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:   (NSInteger)section
{
    id<NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];

    return [sectionInfo numberOfObjects]?:1;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0 && indexPath.item == 0)
{
    AddNewNoteCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"AddNewNoteCell" forIndexPath:indexPath];
    cell.delegate = self;
    return cell;
    }
    else
    {
        NoteCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"NoteCell" forIndexPath:indexPath];
        //Code for customization
    return cell;
   }
}

但这种方法造成了问题。它不会立即添加新创建的备注单元格。如果添加,则新添加的单元格显示为&#34;添加新单元格&#34;。如果我弹出视图控制器并再次加载视图控制器,它会正确显示单元格。

请指导我找到准确的解决方案。 这可能吗?

1 个答案:

答案 0 :(得分:1)

假设你想要&#34;添加新笔记&#34;单元格显示为第一部分中的第一个项目,但不显示在任何其他部分中,您需要修改numberOfItemsInSection方法,以便为第0部分的[sectionInfo numberOfObjects]添加1。对于其他部分,您应该只返回numberOfObjects

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:   (NSInteger)section
{
    id<NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    NSInteger items = [sectionInfo numberOfObjects];
    if (section == 0) items++;
    return items; 
}

然后在cellForItemAtIndexPath:中你可以(如你所愿)将第0节中的第0项视为特殊情况(即给它一个不同的单元子类并相应地配置它)。对于其他单元格,您可以使用indexPath对其进行配置,以获取fetchedResultsController的详细信息。但是,在第0部分中,您需要对此进行调整:单元格0是您的&#34;添加新笔记&#34;单元格,因此您希望单元格1配置fetchedResultsController中项目0的详细信息。构造一个新的indexPath:

NSIndexPath *fetchIndexPath = [NSIndexPath indexPathForItem:(indexPath.row -1) inSection:0];

并使用它从fetchedResultsController获取正确的数据。

我假设您的&#34;添加新笔记&#34;单元格在视图控制器中调用一些方法,以将新的注释对象添加到managedObjectContext。如果实现NSFetchedResultsController委托方法(请参阅docs),则可以使用新添加的对象立即更新collectionView。但是你必须颠倒第0节的上述调整:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    [self.collectionView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{ 
    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.collectionView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]];
            break;

        case NSFetchedResultsChangeDelete:
            [self.collectionView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]];
            break;
    }
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
    NSIndexPath *adjustedIndexPath;
    NSIndexPath *adjustedNewIndexPath;
    if (indexPath.section == 0) {
        adjustedIndexPath = [NSIndexPath indexPathForItem:(indexPath.row+1) inSection:0];
        adjustedNewIndexPath = [NSIndexPath indexPathForItem:(newIndexPath.row+1) inSection:0];
        indexPath = adjustedIndexPath;
        newIndexPath = adjustedNewIndexPath;
    }
    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.collectionView insertItemsAtIndexPaths:@[newIndexPath]];
            break;
        case NSFetchedResultsChangeDelete:
            [self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
            break;
        case NSFetchedResultsChangeUpdate:
            [self configureCell:[self.collectionView cellForItemAtIndexPath:indexPath] atIndexPath:indexPath];
            break;
        case NSFetchedResultsChangeMove:
            [self.collectionView moveItemAtIndexPath:indexPath toIndexPath:newIndexPath];
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.collectionView endUpdates];
}

您应该根据自己的特殊需求定制上述方法(例如,我假设您不希望允许某个部分在第0部分之前移动)。