ios - 修复了 UICollectionView 中的静态单元格

标签 ios objective-c uicollectionview

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

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

我尝试通过以下方式实现它;

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

但是这种方法会引起问题。它不会立即添加新创建的注释单元格。如果添加,则新添加的单元格显示为“添加新单元格”。如果我弹出 View Controller 并再次加载 View Controller ,它会正确显示单元格。

请指导我以获得准确的解决方案。 这可能吗?

最佳答案

假设您希望“添加新注释”单元格显示为第一部分中的第一项,而不是任何其他部分中的第一项,您需要修改您的 numberOfItemsInSection 方法以将 1 添加到[sectionInfo numberOfObjects] 用于第 0 部分。对于其他部分,您应该只返回 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 是您的“添加新注释”单元格,因此您希望单元格 1 使用 fetchedResultsController 中的项目 0 的详细信息进行配置。构造一个新的indexPath:

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

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

我假设您的“添加新注释”单元调用 View Controller 中的某个方法以将新注释对象添加到您的 managedObjectContext。如果您实现了 NSFetchedResultsController 委托(delegate)方法(参见 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 部分之前)。

关于ios - 修复了 UICollectionView 中的静态单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26525744/

相关文章:

ios - UICollectionView 必须使用非零布局参数进行初始化。 UICollectionView 快速出错

ios - 局部变量不会复制到全局变量(swift)

ios - SwiftUI:将动画附加到过渡

IOS navigationController?.popToRootViewController有错

iphone - 从 AVCaptureAudioDataOutputSampleBufferDelegate 播放音频

iphone - Tab 激活时刷新 View

ios - Shopify 购买 SDK : Maintain cart items between view controllers

ios - 影响其他单元格的 Swift Collection View 按钮

iOS:允许用户交互,但在滚动时禁止选择 UICollectionView 中的其他单元格

ios - 处理 UITableViewCell 中的按钮列表