8

インデックス作成をサポートする Core Data に裏打ちされた UITableView を実装しようとしています (例: 横に表示される文字、およびそれらに付随するセクション ヘッダー)。Core Data を使用せずにこれを実装するのにまったく問題はありません:

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

また、インデックスを使用せずに Core Data に基づく UITableView を実装しても問題ありません。

私が理解しようとしているのは、2つをエレガントに組み合わせる方法ですか? 明らかに、コンテンツをインデックス化して再セクション化すると、標準の 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 がすぐに使用できることを知っていますが、私が望むのは、インデックスが人の名の最初の文字である連絡先アプリのような機能を複製することです。

4

1 に答える 1

21

セクション/インデックスを取得するには、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];
}

更新
これは、セクション ヘッダーではなく、インデックスとインデックスの高速スクロールでのみ機能します。セクションヘッダーとインデックスの最初の文字を実装する方法の詳細と詳細については、「最初の文字をセクション名として使用する方法」に対するこの回答
を 参照してください。

于 2009-10-21T20:32:16.287 に答える