核心数据手册示例添加自定义单元格



我的应用程序基于苹果提供的核心数据手册示例项目,我将每个单元格制作成一个自定义单元格,用于显示某些数据,效果神奇。

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

我试过了:

- (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处获得自定义单元格,然后在索引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];
}

我正在实现相同的函数,并使用偏移量和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;
}

用于调整indexpath以从NsFetchedResultController检索正确对象的私有方法。

以下是我应用adjustedIndexPath: 的方法

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

最新更新