Indexed NSFetchedResultsController

¿Cómo puedo indexar un NSFetchedResultsController para que pueda implementar un índice AZ en una tableview.

Veo en el inicializador que puedo hacer sectionNameKeyPath pero esto solo coloca objects únicos en su propia sección.

Esto es lo que tengo para mi NSFetchedResultsController

  - (NSFetchedResultsController *)fetchedResultsController { if (__fetchedResultsController != nil) { return __fetchedResultsController; } NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Customer" inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; [fetchRequest setFetchBatchSize:20]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil]; [fetchRequest setSortDescriptors:sortDescriptors]; NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"name" cacheName:@"Customer"]; aFetchedResultsController.delegate = self; self.fetchedResultsController = aFetchedResultsController; return __fetchedResultsController; } 

implementar sectionIndexTitlesForTableView: así:

 - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { return [self.fetchedResultsController sectionIndexTitles]; } 

Esto le dará esos índices en el lado derecho de tableView.

Si desea que sus secciones tengan nombres como A, B, C, D, etc., debe implementar un método que devuelva la primera letra de su object.

algo como esto:

 - (NSString *)firstLetter { [self willAccessValueForKey:@"firstLetter"]; NSString *firstLetter = [[[self name] substringToIndex:1] uppercaseString]; [self didAccessValueForKey:@"firstLetter"]; return firstLetter; } 

Esto se aplica a la subclass personalizada de su entidad conetworkingata.

A continuación, agregue un atributo transitorio denominado firstLetter a su entidad de datos núcleo y reemplace the sectionNameKeyPath en NSFetchedResultsController init con firstLetter

La respuesta de @Harris mostrará todo el alfabeto al costado de la table. Desafortunadamente, si toca una de las letras que realmente tiene una sección correspondiente, se bloquea con algo como:

 Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Index title at 3 is not equal to 'K'' 

Si desea tener las letras AZ a un lado (aunque no tenga secciones para cada letra), lo hará:

 - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { return [NSArray arrayWithObjects:@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T",@"U",@"V",@"W",@"X",@"Y",@"Z",@"#",nil]; } - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { index = 0; for(id sectionInfo in [_fetchedResultsController sections]){ if ([[[sectionInfo name] uppercaseString] isEqualToString:title]){ break; } index++; } if (index>=[_fetchedResultsController sections].count){ return -1; } return [_fetchedResultsController sectionForSectionIndexTitle:title atIndex:index]; } 

versión correcta (ios 7.1 a 8.3):

 - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { return [NSArray arrayWithObjects:@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T",@"U",@"V",@"W",@"X",@"Y",@"Z",@"#",nil]; } - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { NSInteger section = 0; for (id <NSFetchedResultsSectionInfo> sectionInfo in [_fetchedResultsController sections]) { if ([sectionInfo.indexTitle compare:title] >= 0) { break; } section++; } return section; }