8

Ich versuche, ein Core Data Backed UITableView zu implementieren, die Indexierung unterstützt (zB: die Zeichen, die auf der Seite erscheinen, und die Abschnittskopfzeilen, die zu ihnen gehören). Ich habe keine Probleme bei all dies ohne Core Data Umsetzung mit:Core Data gesichert UITableView mit Indizierung

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

Ich habe auch kein Problem, einen UITableView implementieren, ohne die Indizierung von Core Data unterstützt wird.

Was ich herausfinden möchte, ist, wie man die zwei elegant kombiniert? Sobald Sie den Inhalt indexieren und neu gruppieren, können Sie den Standard-NSFetchedResultsController nicht mehr verwenden, um Objekte in einem bestimmten Indexpfad abzurufen. Also speichere ich meine Indexbuchstaben in einem NSArray und meinen indizierten Inhalt in einem NSDictionary. Das alles funktioniert für die Anzeige in Ordnung, aber ich habe einige echte Kopfschmerzen, wenn es um das Hinzufügen und Löschen von Zeilen, wie speziell richtig diese Methoden implementieren:

- (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; 

Da die Indexpfade ist es mir zurückkehrt haben keine Korrelation mit denen, in Kerndaten. Ich habe add funktioniert, indem ich einfach meine index NSArray und NSDictionary neu erstellen, wenn der Benutzer eine Zeile hinzufügt, aber das gleiche tun, wenn sie eine löschen stürzt die ganze Anwendung ab.

Gibt es ein einfaches Muster/Beispiel, das ich hier vermisse, um das alles richtig zu machen?

Edit: Nur um zu klären, ich weiß, dass die NSFetchedResultsController tut dies out-of-the-box, aber was ich will, ist die Funktionalität wie die Kontakte-App zu replizieren, wobei der Index der erste Buchstabe des Vornamens der Person ist.

Antwort

20

Sie sollten Ihre CoreData NSFetchedResultsController verwenden, um Ihre Abschnitte/Indizes abzurufen.
Sie den Abschnitt Schlüssel in der Abrufanforderung angeben kann (ich denke, es ist die erste Sortierschlüssel übereinstimmen muss):

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section]; 
    return [sectionInfo name]; 
} 

:

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; 

Dann können Sie die Abschnittsnamen wie diese erhalten, und die Sektion Indizes sind hier:

id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section]; 
[sectionInfo indexTitle]; // this is the index 

Änderungen am Inhalt nur anzeigen, dass die Tabelle aktualisiert werden muss:

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

UPDATE
Dies funktioniert nur für den Index und schnell Index Scrollen, nicht für die Abschnittsüberschriften.
Siehe "this answer" zu "Verwendung des ersten Zeichens als Abschnittsname" für weitere Informationen und Details zum Implementieren von Anfangsbuchstaben für Abschnittsüberschriften sowie für den Index.

+0

Ich denke, ich habe mich nicht klar genug gemacht. Ich möchte, dass meine Indizes genau wie die Kontakt-App, der erste Buchstabe des Vornamens der Person, sind. – rustyshelf

+0

Also, warum funktioniert die Verwendung des ersten Namens als sectionNameKeyPath nicht? – gerry3

+0

sectionNameKeyPath! ??!?! ??! Wie zum Teufel habe ich das vermisst! Wow, das funktioniert super. Ich hätte die Doco besser lesen sollen, bevor ich meine eigene geschrieben habe ... bin darauf zurückgegangen und es funktioniert süß. Ich würde dir +5000 geben, wenn ich könnte;) – rustyshelf