我正在尝试实现支持索引的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是开箱即用的,但我想要的是复制像Contacts应用程序这样的功能,其中索引是该人名的第一个字母。 / p>
答案 0 :(得分:21)
您应该使用CoreData NSFetchedResultsController来获取您的部分/索引 您可以在获取请求中指定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到“如何将第一个字符用作节名称”。