核心数据支持 UITableView 索引 [英] Core Data backed UITableView with indexing

查看:17
本文介绍了核心数据支持 UITableView 索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现一个支持索引的 Core Data 支持的 UITableView(例如:出现在侧面的字符,以及伴随它们的部分标题).在没有核心数据的情况下,我完全没有问题:

I am trying to implement a Core Data backed UITableView that supports indexing (eg: the characters that appear down the side, and the section headers that go with them). I have no problems at all implementing this without Core Data using:

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

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

I also have no problem implementing a UITableView that is backed by Core Data without using the indexing.

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

What I am trying to figure out is how to elegantly combine the two? Obviously once you index and re-section content, you can no longer use the standard NSFetchedResultsController to retrieve things at a given index path. So I am storing my index letters in an NSArray and my indexed content in an NSDictionary. This all works fine for display, but I have some real headaches when it comes to adding and deleting rows, specifically how to properly implement these methods:

- (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 来添加工作,但是当他们删除一个时执行相同的操作会导致整个应用程序崩溃.

Because the index paths it's returning me have no correlation with the ones in core data. I got add working by simply rebuilding my index NSArray and NSDictionary when the user adds a row, but doing the same when they delete one crashes the whole application.

是否有我在这里缺少的简单模式/示例可以使所有这些正常工作?

Is there a simple pattern/example I'm missing here to make all this work properly?

只是为了澄清我知道 NSFetchedResultsController 开箱即用,但我想要的是复制像联系人应用程序这样的功能,其中索引是人名的第一个字母.

Just to clarify I know that the NSFetchedResultsController does this out of the box, but what I want is to replicate the functionality like the Contacts app, where the index is the first letter of the first name of the person.

推荐答案

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

You should use your CoreData NSFetchedResultsController to get your sections/indexes.
You can specify the section key in the fetch request (I think it has to match the first sort key):

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;

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

Then, you can get the section names like this:

- (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

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

Changes to the content just indicate that the table needs to be updated:

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

更新
这仅适用于索引和快速索引滚动,不适用于节标题.
请参阅此答案如何将第一个字符用作节名称",了解有关如何为节标题和索引实现首字母的更多信息和详细信息.

UPDATE
This only works for the index and fast index scrolling, not for the section headers.
See this answer to "How to use the first character as a section name" for more information and details on how to implement first letters for section headers as well as the index.

这篇关于核心数据支持 UITableView 索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆