8

我想实现一个支持索引的Core Data支持的UITableView(例如:出现在边下的字符以及与它们一起出现的节头)。我没有问题,在所有使用此实现无核心数据:核心数据支持UITableView与索引

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

我也有实现由核心数据的支持,而无需使用索引一个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开箱即用,但我想要的是复制类似于联系人应用程序的功能,其中索引是人物名字的第一个字母。

回答

20

您应该使用CoreData NSFetchedResultsController来获取您的节/索引。
您可以指定获取请求的部分键(我认为它相匹配的第一个排序关键字):

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]; 
} 

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

+0

我想我没有让自己清楚。我希望我的索引像联系人应用程序一样,是人名的第一个字母。 – rustyshelf 2009-10-21 23:14:50

+0

那么,为什么不使用第一个名称作为sectionNameKeyPath的工作? – gerry3 2009-10-23 03:59:16

+0

sectionNameKeyPath!??!?!??!我怎么错过了!哇,这工作辉煌。在编码自己之前,我应该更好地阅读doco ......已经恢复到了这一点,并且工作得很好。如果可以的话,我会给你+5000;) – rustyshelf 2009-10-30 01:08:08