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