2010-01-30 11 views
12

Ho aggiunto un elenco di sezioni per una semplice app di iPhone Core Data.Caratteri non statunitensi nelle intestazioni di sezione per UITableView

Ho seguito questa domanda così per crearlo - How to use the first character as a section name ma la mia lista contiene anche voci che iniziano con caratteri fuori dalla A-Z, specialmente Å, Ä e Ö usati qui in Svezia.

Il problema ora è che quando la vista tabella mostra l'elenco delle sezioni, gli ultimi tre caratteri vengono disegnati in modo errato. Vedi immagine qui sotto

Sembra che la mia migliore opzione in questo momento è quello di lasciare che tali elementi sono ordinati in 'Z'

if ([letter isEqual:@"Å"] || 
    [letter isEqual:@"Ä"] || 
    [letter isEqual:@"Ö"]) 
    letter = @"Z"; 

Qualcuno che hanno capito questo fuori?

E mentre io sono a esso ... 'A', 'A' e 'O' devono essere ordinati in questo ordine, ma vengono ordinati come 'A', 'A' e 'O' con Core Data NSSortDescriptor . Ho provato a impostare il selettore su localizedCaseInsensitiveCompare: ma questo dà un errore out of order section name 'Ä. Objects must be sorted by section name'. Visto anche quello?

+0

Vedere la mia risposta a una domanda simile [qui] (http://stackoverflow.com/a/13292767/616764), in cui descrivo come creare indici sectionKey localizzati. –

risposta

3

Quando incontro una situazione come questa, la prima cosa che mi chiedo è "cosa fa Apple".

Come esperimento ho appena aggiunto "Joe Äpple" alla rubrica del mio iPhone e lui si presenta sotto la pianura A. Penso che abbia molto senso.

Quindi invece di lanciarli sotto Z o Ä dovresti fare lo stesso. Ci deve essere un modo per ottenere la lettera 'base' di un carattere unicode per il raggruppamento.

+0

+1 Buon punto. Ne ho provati alcuni anche qui e in effetti lo fa in modo diverso a seconda della lingua selezionata in Impostazioni. Pensa che ora ho capito lo smistamento. Ma ancora non riesco a farlo disegnare correttamente ... – epatel

1

Hai seguito il mio answer per quell'altra domanda?

Sto facendo alcuni test (il recupero dei miei oggetti) e vedo strani comportamenti intermittenti. Li ordina in modo corretto (con 'Å' subito dopo 'A', ma prima di 'Ä') a volte. Altre volte mette i personaggi fuori dalla A-Z alla fine (dopo "Z") anche se non ho fatto niente di speciale.

Inoltre, ho notato che "Å" viene disegnato correttamente se si restituisce la sua forma minuscola. Hai provato a sovrascrivere sectionIndexTitleForSectionName: per mantenere l'ordine, ma modificare il carattere disegnato?

+0

+1 Sì, basando la mia soluzione dei tuoi consigli lì, grazie! Cerco di fidarmi di Core Data il più possibile. Esaminerà la sottoclasse di NSFetchedResultsController, prima prova fallita – epatel

+0

Questa non è una sottoclasse, è un metodo che puoi implementare nella tua vista tabella delegato. – gerry3

+0

Pensavo fosse un metodo (sectionIndexTitleForSectionName :) sul controller durante la lettura dei documenti ?! – epatel

15

Quindi non potevo lasciare andare questo e trovato il seguente:

Quello che dovete fare in questo caso si chiama 'normalizzazione Unicode Modulo D'. È più spiegato in http://unicode.org/reports/tr15/ (avviso, documento lungo e secco)

Ecco una funzione che esegue la scomposizione e quindi filtra tutti i segni diacritici. Puoi usare questo per convertire Äpple in Apple e quindi usare la prima lettera per costruire un indice.

- (NSString*) decomposeAndFilterString: (NSString*) string 
{ 
    NSMutableString *decomposedString = [[string decomposedStringWithCanonicalMapping] mutableCopy]; 
    NSCharacterSet *nonBaseSet = [NSCharacterSet nonBaseCharacterSet]; 
    NSRange range = NSMakeRange([decomposedString length], 0); 

    while (range.location > 0) { 
     range = [decomposedString rangeOfCharacterFromSet:nonBaseSet 
      options:NSBackwardsSearch range:NSMakeRange(0, range.location)]; 
     if (range.length == 0) { 
      break; 
     } 
     [decomposedString deleteCharactersInRange:range]; 
    } 

    return [decomposedString autorelease]; 
} 

(ho trovato questo codice su una mailing list, dimenticato la fonte, ma ho preso e ha risolto il tutto un po ')

+1

+1 per la ricerca e l'interesse. Ma penso di aver inchiodato lo smistamento ora. Io uso 'localizedCaseInsensitiveCompare:' per un descrittore di ordinamento per il controller dei risultati recuperato, che manterrà l'ordine come impostazione della lingua sul dispositivo. Ma i titoli indice ecc. Sono gestiti da CoreData come gerry3 descritto qui http://stackoverflow.com/questions/1741093/how-to-use-the-first-character-as-a-seection-name/1741131#1741131 – epatel

+0

Questo sfortunatamente non funziona con * Æ * lettera – Shmidt

1

Hai mai risolvere questo problema?

Sono stato in grado di ottenere l'indice di titolo della sezione per visualizzare correttamente implementando sectionIndexTitlesForTableView: costruire il mio gamma di titoli delle sezioni:

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { 

    NSMutableArray *indexKeys = [NSMutableArray arrayWithCapacity:30]; 
    NSArray *fetchedResults = [fetchedResultsController fetchedObjects]; 
    NSString *currKey = @"DEFAULT"; 

    for (NSManagedObject *managedObject in fetchedResults) { 
     NSString *indexKey = [managedObject valueForKey:@"indexKey"]; 
     if (![indexKey isEqualToString:currKey]) { 
      [indexKeys addObject:indexKey]; 
      currKey = indexKey; 
     } 
    } 

    return indexKeys; 
} 

Qui, indexKey è la prima lettera del nome.

Tuttavia, questo crea uno dei due temi in sectionForSectionIndexTitle: invece:

Se ho semplicemente restituire l'indice per la sezione questo è ora l'indice misti e non corrisponde più con l'ordinamento nella fetchResultController:

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { 
    return index; 
} 

in alternativa, se mi passa la chiamata al fetchedResultsController si rompe sui titoli dell'indice fuori degli Stati Uniti, perché questi non sono più i personaggi strani utilizzati dal fetchedResultsController:

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

Quest'ultimo codice genera un errore del seguente tipo durante la navigazione per la "O" titolo dell'indice:

terminazione app a causa di eccezione non identificata 'NSInternalInconsistencyException', la ragione: 'indice del titolo a 24 non è uguale a 'O''

Una soluzione per questo è di tradurre i caratteri problematici di nuovo a loro stessi strani:

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { 
    if ([title isEqualToString:@"Æ"]) { 
     title = @"\u2206"; 
    } else if ([title isEqualToString:@"Ø"]) { 
     title = @"\u0178"; 
    } else if ([title isEqualToString:@"Å"]) { 
     title = @"\u2248"; 
    } 
    return [fetchedResultsController sectionForSectionIndexTitle:title atIndex:index]; 
} 

È possibile trovare la Valori Unicode nel debugger con l'azione "Stampa descrizione in console".

Tuttavia, la soluzione migliore sarebbe capire perché questa codifica strana accade e impedirlo.

+0

Devo provare questo ... – epatel

4

Sto riscontrando lo stesso problema riportato nella domanda originale, vale a dire caratteri estesi (all'esterno della pagina Unicode 0) non visualizzati correttamente nella barra dell'indice.

Anche se mi sembra di nutrire NSFetchedResultsController con stringhe di caratteri single unicode corrette, quello che ottengo in cambio dell'accesso alla proprietà 'sectionIndexTitles' sono quegli stessi caratteri con il byte alto impostato su 0; per esempio il carattere \ u30a2 (KATAKANA LETTERA A) diventa \ u00a2 (SEGNO CENT).

Non sono sicuro se questo è un bug nel metodo sectionIndexTitleForSectionName: di NSFetchedResultsController o colpa mia da qualche altra parte, tuttavia la mia soluzione consiste nel override e l'esecuzione di ciò che la documentazione dice che fa internamente:

- (NSString *)sectionIndexTitleForSectionName:(NSString *)sectionName 
{ 
    NSString *outName; 

    if ([sectionName length]) 
     outName = [[sectionName substringToIndex:1] uppercaseString]; 
    else 
     outName = [super sectionIndexTitleForSectionName:sectionName]; 

    return outName; 
} 

Questo produce l'uscita prevista.

+0

Sembra promettente. Devo provare ... se riesco solo a trovare di nuovo i file di progetto;) – epatel

+1

Questo è stato un vantaggio molto buono, tuttavia questo non è sufficiente per set di caratteri più complessi come il tailandese. In questo caso dovresti usare '[[sectionName substringWithRange: [sectionName rangeOfComposedCharacterSequenceAtIndex: 0]] uppercaseString];' – FelixLam

+0

Posso confermare che ha funzionato bene. Deve essere un bug –

4

Solo l'aggiunta di questo nel mio controller ha risolto il problema originale per me

- (NSString *)controller:(NSFetchedResultsController *)controller sectionIndexTitleForSectionName:(NSString *)sectionName { 
return sectionName;} 

Å, Ä e Ö visualizza correttamente nell'elenco

+1

Vedere il mio commento sopra 'substringToIndex: 1' non funziona per i caratteri UTF. Utilizza invece: '[[sectionName substringWithRange: [sectionName rangeOfComposedCharacterSequenceAtIndex: 0]] uppercaseString];' – FelixLam

+0

Funziona per me? NSString * s = @ "ÉÎØÜ"; \t NSLog (@ "% @", [s substringToIndex: 1]); \t NSLog (@ "% @", [s sottostringaWithRange: [s rangeOfComposedCharacterSequenceAtIndex: 0]] uppercaseString]); 2014/08/19 15: 01: 15,054 Test [53092: 3.703.902] É 2014/08/19 15: 01: 15,055 Test [53092: 3.703.902] É A meno che non ci sia un altro personaggio che fallirebbe qui ... – codepoet

2

È possibile utilizzare codifica UTF-8

const char *cLetter = (const char *)[ tmp cStringUsingEncoding:NSUTF8StringEncoding]; 
NSString *original = [NSString stringWithCString:cLetter encoding:NSUTF8StringEncoding]; 
Problemi correlati