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

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

问题描述

我试图实现支持索引的核心数据支持的UITableView(例如:侧面显示的字符,以及与它们一起使用的节头)。我没有问题在所有实现这个没有Core Data使用:

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

我没有使用索引来实现由Core Data支持的UITableView也没有问题。 p>

我想弄清楚的是如何优雅地结合两者?很显然,一旦你索引和重新编写内容,你不能再使用标准的NSFetchedResultsController在给定的索引路径检索东西。所以我存储我的索引字母在NSArray和我的索引内容在NSDictionary。这一切都适用于显示,但我有一些真正的头痛,当涉及到添加和删除行,具体如何正确实施这些方法:

   - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller; (NSFetchedResultsChangeType)类型newIndexPath:(NSIndexPath *)newIndexPath;(NSFetchedResultsController *)控制器didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType: 

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

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

因为它返回的索引路径与核心数据中的索引路径没有相关性。我添加了工作,当用户添加一行时,只是重建我的索引NSArray和NSDictionary,但如果删除一个会导致整个应用程序崩溃。



简单模式/示例我在这里缺少所有这一切正常工作?



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

解决方案

p>您应该使用您的CoreData NSFetchedResultsController来获取您的节/索引。

您可以在fetch请求中指定节键(我认为它必须与第一个排序键匹配):



NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:@name//此键定义排序
:是];
NSArray * sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor,nil];
[fetchRequest setSortDescriptors:sortDescriptors];

NSFetchedResultsController * aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext
sectionNameKeyPath:@name//此键定义节
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]; //这是索引

对内容的更改只是指示表需要更新: / p>

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

UPDATE

仅适用于索引和快速索引滚动,而不适用于节标题。

请参见这个答案到如何使用第一个字符作为节名以获取更多信息以及如何为节首部实现第一个字母的详细信息以及索引。


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;

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

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;

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?

Edit: 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.

解决方案

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

And the section indexes are here:

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天全站免登陆