2012-08-01 17 views
6

Ho implementato una tastiera personalizzata associata a un campo di testo, quindi quando l'utente preme il pulsante Elimina, rimuovo l'ultimo carattere dalla stringa e aggiorno manualmente il testo del campo di testo corrente .Come rimuovere l'ultimo simbolo Unicode da NSString

NSRange range = NSMakeRange(currentTextFieldString.length-1, 1); 
[currentTextFieldString replaceCharactersInRange:range withString:@""]; 

Fin qui tutto bene.

Ora, il problema è che l'utente ha la possibilità di inserire alcuni simboli speciali Unicode, questi non sono 1 byte, possono essere anche 2 byte, ora premendo il pulsante Elimina, devo rimuovere l'intero simbolo , ma se seguo l'approccio di cui sopra, l'utente deve premere due volte il pulsante di cancellazione.

Qui, se faccio:

NSRange range = NSMakeRange(currentTextFieldString.length-2, 2); 
[currentTextFieldString replaceCharactersInRange:range withString:@""]; 

funziona benissimo, ma d'altra parte, i caratteri normali, che sono solo 1 byte, vengono eliminati due volte alla volta.

Come gestire tali scenari?

Grazie in anticipo.

EDIT:

E 'strano, che se posso passare alla tastiera iPhone, gestisce entrambi i casi in modo appropriato. Ci deve essere un modo per farlo, c'è qualcosa che mi manca, ma non sono in grado di capire cosa.

+0

In che modo la tastiera personalizzata aggiunge caratteri? – Joe

+0

La mia risposta a questa domanda potrebbe aiutarti http://stackoverflow.com/q/11567049/1487063 – Dustin

+0

@Joe: ogni volta che l'utente preme un pulsante, prendo il carattere corrispondente, lo aggiungo al testo corrente del campo di testo, e assegnarlo come testo per il campo di testo. –

risposta

16

Ecco il problema. Le NSString sono codificate usando UTF-16. Molti glifi Unicode comuni occupano solo uno unichar (un valore senza segno a 16 bit). Tuttavia, alcuni glifi occupano due unichar. Ancora peggio, alcuni glifi possono essere composti o scomposti, ad esempio potrebbe essere un punto di codice Unicode o potrebbe essere due - un accento acuto seguito da una e. Questo rende piuttosto difficile fare ciò che si vuole eliminare un "personaggio" perché è davvero difficile dire quanti unichar ci vogliono.

Fortunatamente, NSString ha un metodo che aiuta con questo: -rangeOfComposedCharacterSequenceAtIndex:.Quello che devi fare è ottenere l'indice dell'ultimo unichar, eseguire questo metodo su di esso e il NSRange restituito ti dirà dove cancellare. Va qualcosa di simile a questo (non testato):

NSUInteger lastCharIndex = [myString length] - 1; // I assume string is not empty 
NSRange rangeOfLastChar = [myString rangeOfComposedCharacterSequenceAtIndex: lastCharIndex]; 
myNewString = [myString substringToIndex: rangeOfLastChar.location]; 
+0

+1 Questo è esattamente quello che stavo cercando.Questo funziona alla grande.Alcuni metodi sono nascosto nel profondo dei documenti per scoprirlo. –

0

Se non si riesce a far funzionare tutto in modo predefinito, utilizzare un blocco if/else e verificare se l'ultimo carattere fa parte di un carattere speciale. In tal caso, utilizzare la sottostringa su length-2, altrimenti utilizzare la sottostringa su length-1.

+0

Grazie per la risposta! Ma non sarebbe un problema, se dici che l'utente inserisce un carattere dalla tastiera, dì @/#/$ ecc. Se controllo se l'ultimo carattere è un carattere speciale, sarebbe vero in questo caso, e dovremmo cancella 2 caratteri, dove dovevamo eliminarne uno? –

+0

Voglio dire, nella tua istruzione if controlla i caratteri specifici che ti stanno dando problemi. Non quelli che non lo sono. – Dustin

+0

Oh sì, ma alcuni che mi stanno dando problemi esistono in entrambi :) Questo è il punto cruciale del mio problema. –

0

Non so esattamente quale sia il problema con la lunghezza del byte dei caratteri speciali.

cosa che suggerisco è:

  • Conservare lunghezza della stringa ad un parametro, prima di aggiungere eventuali nuovi personaggi
  • Se l'utente seleziona backspace (rimuovere ultimi caratteri) quindi rimuovere la stringa da ultimo tratto di nuova lunghezza. Per esempio, l'ultima lunghezza della stringa salvata è 5 e la nuova lunghezza della stringa è 7, quindi rimuovere una nuova stringa con l'indice da 0 a 4, in modo da ritagliare i caratteri rimanenti.

Questo è il contrario per fare come non so esattamente quale problema internamente.

Ma immagino che questa soluzione dovrebbe funzionare logicamente.

Godetevi la codifica :)

+0

Oh sì, questo dovrebbe funzionare credo. Grazie per la risposta, ma sono ancora confuso su come risolverlo con un approccio più metodologico. Ho provato tutti i tipi di cose, come convertirlo in NSData, quindi rimuovere i byte, per vedere cosa succede realmente, ma senza risultato :( –

Problemi correlati