8

Ho uno NSFetchedResultsController che recupera i dati da una struttura Core Data, un elenco di album. Attualmente è ordinato dall'artista, quindi tutti gli A, i B, ecc. Voglio aggiungere un indice in modo che l'utente possa saltare rapidamente a ogni lettera e sto usando il codice qui sotto per farlo. Il problema è che le intestazioni di sezione sono ora "A", "B", "C", ecc., Il che significa che ho perso le intestazioni di sezione in ordine alfabetico con ogni singolo artista su di esso ("Adele", "America "," Beatles, The ", ecc.)Indice A-Z da NSFetchedResultsController con intestazioni di sezione individuali all'interno di ogni lettera?

Mi piacerebbe che l'indice utilizzi le lettere dalla A alla Z, ma le intestazioni delle sezioni per visualizzare i nomi degli artisti in ordine alfabetico. Spingendo una lettera nell'indice, si passerebbe quindi al primo artista con quella lettera. Come posso ottenerlo (caratteri alfabetici nell'indice, ma un attributo diverso per i titoli delle sezioni)?

EDIT: Se ho impostato la mia sectionNameKeyPath al mio author campo, l'indice AZ è visibile, ma le lettere non vengono sincronizzati fino ai nomi, per esempio se si tocca S, mi ci vuole per gli artisti che iniziano con AL, o toccando G mi porta in AB. Non sono del tutto sicuro del motivo, forse l'indice della sezione sta rovinando?

Ecco il codice che sto utilizzando:

Nel mio NSManagedObject sottoclasse:

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

Nel mio controller della vista, per creare la FRC:

NSFetchedResultsController *byAuthorFRC = [[NSFetchedResultsController alloc] initWithFetchRequest: _fetchRequest 
                       managedObjectContext: [[CDManager sharedManager] managedObjectContext] 
                       sectionNameKeyPath: @"firstLetter" 
                         cacheName: nil]; 

Ed ecco il mio metodo sectionIndexTitlesForTableView::

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

Cosa succede se si utilizza 'sectionNameKeyPath: @" author "'? –

+0

@MartinR C'è un indice A-Z, ma le lettere non sono sincronizzate con i nomi, ad esempio se tocco S, mi porta agli artisti che iniziano con AL, o toccando G mi porta in AB. – Luke

+0

prova questo [collegamento] (http://stackoverflow.com/questions/15883892/custom-core-data-sectionnamekeypath/15885824#15885824) –

risposta

16

sectionNameKeyPath:@"author"è il parametro corretto, perché è così che si desidera che il tavolo raggruppati in sezioni. L'implementazione standard

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

restituisce la prima lettera di ogni intestazione di sezione, quindi non c'è necessità di un metodo separato firstLetter.

Per la corretta sincronizzazione dall'indice sezione sezioni si necessario implementare il metodo origine dati vista tabella tableView:sectionForSectionIndexTitle:atIndex:.L'implementazione standard in relazione con un controller risultati inverosimile è:

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index 
{ 
    return [self.fetchedResultsController sectionForSectionIndexTitle:title atIndex:index]; 
} 

Edit:

Swift:

func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? { 
    return fetchedResultsController.sectionIndexTitles 
} 

func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int { 
    return fetchedResultsController.sectionForSectionIndexTitle(title, atIndex: index) 
} 
2

Swift 2

Aggiungi questa var al tuo NSManagedObject

class Adherent: NSManagedObject { 

    var initialNom: String { 
     self.willAccessValueForKey("initialNom") 
     let initial = (self.nom as NSString).substringToIndex(1) 
     self.didAccessValueForKey("initialNom") 
     return initial 
    } 

} 

poi usarlo nella vostra NSFetchedResultsController costruttore (non dimenticate di sorta con l'attributo "reale")

let nomSort = NSSortDescriptor(key: "nom", ascending: true) 
request.sortDescriptors = [nomSort] 

self.fetchedResultController = NSFetchedResultsController(
    fetchRequest: request, 
    managedObjectContext: managedObjectContext, 
    sectionNameKeyPath: "initialNom", 
    cacheName: nil) 

Secondo te vista tabella, implementare (almeno) questi :

func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
    return self.fetchedResultController.sections!.count 
} 

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    let sections = self.fetchedResultController.sections! 
    let sectionInfo = sections[section] 
    return sectionInfo.numberOfObjects 
} 

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    [...] 
} 

func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? { 
    return self.fetchedResultController.sectionIndexTitles 
} 

func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int { 
    return self.fetchedResultController.sectionForSectionIndexTitle(title, atIndex: index) 
} 

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 
    return self.fetchedResultController.sectionIndexTitles[section] 
} 
Problemi correlati