【问题标题】:Core Data backed UITableView with indexingCore Data 支持 UITableView 和索引
【发布时间】:2010-12-08 14:59:08
【问题描述】:

我正在尝试实现一个支持索引的 Core Data 支持的 UITableView(例如:出现在侧面的字符,以及与它们一起出现的部分标题)。如果没有使用 Core Data,我完全没有问题:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView;

在不使用索引的情况下实现由 Core Data 支持的 UITableView 也没有问题。

我想弄清楚的是如何优雅地将两者结合起来?显然,一旦您索引和重新分段内容,您就不能再使用标准 NSFetchedResultsController 来检索给定索引路径的内容。因此,我将索引字母存储在 NSArray 中,将索引内容存储在 NSDictionary 中。这一切都可以很好地显示,但是在添加和删除行时我确实有些头疼,特别是如何正确实现这些方法:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller;

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

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

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller;

因为它返回给我的索引路径与核心数据中的索引路径没有关联。当用户添加一行时,我通过简单地重建我的索引 NSArray 和 NSDictionary 来添加工作,但是当他们删除一个时执行相同操作会使整个应用程序崩溃。

我在这里缺少一个简单的模式/示例来使所有这些正常工作吗?

编辑:澄清一下,我知道 NSFetchedResultsController 是开箱即用的,但我想要的是复制联系人应用程序等功能,其中索引是人名的第一个字母。

【问题讨论】:

    标签: iphone core-data uitableview nsfetchedresultscontroller cocoa-design-patterns


    【解决方案1】:

    您应该使用 CoreData NSFetchedResultsController 来获取您的部分/索引。
    可以在 fetch 请求中指定 section 键(我认为它必须匹配第一个排序键):

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
    initWithKey:@"name" // this key defines the sort
    ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];
    
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext
    sectionNameKeyPath:@"name" // this key defines the sections
    cacheName:@"Root"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;
    

    然后,您可以像这样获取部分名称:

    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
        id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
        return [sectionInfo name];
    }
    

    章节索引在这里:

    id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
    [sectionInfo indexTitle]; // this is the index
    

    内容的变化只是表明表格需要更新:

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

    更新
    这仅适用于索引和快速索引滚动,不适用于节标题。
    请参阅this answer 到“如何使用第一个字符作为部分名称”以获取有关如何为部分标题和索引实现首字母的更多信息和详细信息。

    【讨论】:

    • 我觉得我说得不够清楚。我希望我的索引就像联系人应用程序一样,是人名的第一个字母。
    • 那么,为什么不使用名字作为 sectionNameKeyPath 呢?
    • sectionNameKeyPath!??!?!??!我怎么错过了!哇,效果很好。在编写自己的代码之前,我应该更好地阅读 doco ......已经恢复到那个状态并且它工作得很好。如果可以的话,我会给你 +5000 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-15
    相关资源
    最近更新 更多