核心数据书籍示例添加自定义单元格

Posted

技术标签:

【中文标题】核心数据书籍示例添加自定义单元格【英文标题】:Core Data Books Example Add Custom Cell 【发布时间】:2012-01-15 23:41:45 【问题描述】:

我的应用程序基于 Apple 提供的 Core Data Books 示例项目,并且我将每个单元格设为自定义单元格,用于显示某些数据,可以神奇地工作。

但是,现在我正在尝试添加第二个自定义单元格。它是一个单一的单元格,它将始终是表格中的第一个单元格,然后从核心数据中获取的所有结果都低于该单元格。

我试过这样:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    
    if (indexPath.row == 0) 
    
        static NSString *CellIdentifier = @"statsCell";

        GuestStatsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) 
        
            cell = [[GuestStatsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        

        //Configure the cell.
        [self configureStatsCell:cell];

        return cell;
    
    else
    
        static NSString *CellIdentifier = @"guestCell";

        customGuestCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) 
        
            cell = [[customGuestCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        

        // Configure the cell.
        [self configureGuestCell:cell atIndexPath:indexPath];

        return cell;
    

以及其他一些更改以尝试使事情正常进行。一些问题。

首先,视图加载正常,我在索引 0 处获得了我的自定义单元格,然后我的核心数据单元格在该索引下方加载。第一个问题,第一个核心数据单元格不可见,因为它隐藏在我的自定义单元格后面,但如果我点击它,我会得到该核心数据条目的详细视图。所以我需要弄清楚如何阻止它在那个自定义单元格后面。

我已经尝试过解决这个问题,例如,这个块似乎是合乎逻辑的:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 

    id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];

因此,这只是为核心数据记录设置了足够的单元格,而不考虑额外的自定义单元格。所以我尝试了一些简单的事情:

return [sectionInfo numberOfObjects] + 1;

然后这导致这一行导致我遇到崩溃和索引超出范围错误:

GuestInfo *guest = [fetchedResultsController objectAtIndexPath:indexPath];

该行来自设置核心数据记录单元的 configureCell 方法。所以我很困惑该怎么做。

下一个问题,当我在详细视图中编辑任何核心数据记录的属性时,返回到表格视图我的自定义单元格没有显示任何更改。它显示与核心数据信息有关的统计信息。只有其他单元格得到更新。

任何帮助将不胜感激,如果您需要查看更多代码或需要更多解释,请告诉我。

编辑:

根据要求提供更多代码来帮助我。这是 NSFetchedController 代码。

- (NSFetchedResultsController *)fetchedResultsController 


    if (fetchedResultsController != nil) 
    
        return fetchedResultsController;
    

    // Create and configure a fetch request with the Book entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"GuestInfo" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];

    // Create the sort descriptors array.
    NSSortDescriptor *lastNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastName" ascending:YES];
    NSSortDescriptor *firstNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:lastNameDescriptor, firstNameDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];

    // Create and initialize the fetch results controller.
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"displayOrder" cacheName:@"Root"];

    self.fetchedResultsController = aFetchedResultsController;
    fetchedResultsController.delegate = self;

    // Memory management.
    //No releasing with ARC!

    return fetchedResultsController;
    


/**
 Delegate methods of NSFetchedResultsController to respond to additions, removals and so on.
 */

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller 
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    [self.tableView beginUpdates];



- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath 

    UITableView *tableView = self.tableView;

    switch(type) 

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureGuestCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            [self.tableView reloadData];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    



- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type 

    switch(type) 

        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    



- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    [self.tableView endUpdates];

【问题讨论】:

您是否启用ARC?如果不是,则 -tableView:cellForRowAtIndexPath: 返回的单元格应自动释放。 你使用了NSFetchedResultController。那么,您能否发布有关配置 fetchedResultController 的代码?还有关于 [fetchedResultsController performFetch:...] 的代码。顺便说一句,在改变一个托管对象的属性之后,你是否调用 [tableView reloadData] 来更新表格视图? 是的,我正在使用 ARC。调用[self.tableView reloadData] 有助于解决在我的单个自定义单元格上重新加载数据的问题。但是仍然需要解决奇怪的单元格重叠问题,我会发布您要求的代码。 也许是更简单的说法。我希望我的自定义单元格位于表格视图中的索引 0 处。然后所有核心数据都获取结果以进行跟踪。目前核心数据结果从索引0开始,我该如何调整? 每个部分都需要这个自定义单元格吗?如果是,-tableView:numberOfRowsInSection: 应该返回 `1+[sectionInfo numberOfObjects]。并且使用 fetechedResultController 返回单元格时需要手动调整索引路径。 【参考方案1】:

我正在实现相同的功能并使用带有 indexPath 的偏移量 @Toro 的解决方案工作得很好。不知道有没有更好的办法,这里是我为有兴趣的人调整的。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects] + 1;

为我的自定义单元格添加一个额外的行,我获取的结果没有部分,所以我可以正常工作。

- (NSIndexPath *)adjustedIndexPath:(NSIndexPath *)indexPath

    NSIndexPath *newPath = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];
    return newPath;

调整索引路径以从 NsFetchedResultController 检索正确对象的私有方法。

这是我申请的方法adjustedIndexPath:

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

【讨论】:

以上是关于核心数据书籍示例添加自定义单元格的主要内容,如果未能解决你的问题,请参考以下文章

Grid布局(四)单元格自定义布局

如何用Apache POI读取Excel的单元格自定义名称的值

UITableview中的按钮修改当前单元格自定义

handsontable 给单元格自定义属性

TableView 单元格自定义类型文本自身重叠或为空白

如何在 KendoGrid 单元格自定义单击上将 dataItem 传递给 js 函数