comment déplacer le curseur dans UITextField après avoir défini sa valeur
est-ce que n'importe qui peut m'aider avec ceci: j'ai besoin d'implémenter UITextField
pour le nombre d'entrée. Ce nombre doit toujours être de forme décimale avec 4 places par exemple 12.3456 ou 12.3400.
J'ai donc créé NSNumberFormatter
qui m'aide avec des décimales.
je mets la valeur UITextField
dans
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
méthode.
Je proccess entrée, Utiliser formatter et finalement appeler [textField setText: myFormattedValue];
Cela fonctionne bien, mais cet appel aussi déplace le curseur à la fin de mon domaine. Qui est indésirable. Par exemple: J'ai 12.3400 dans mon champ et le curseur est situé au tout début et les types d'utilisateur numéro 1. La valeur du résultat est 112.3400 mais le curseur est déplacé à la fin. Je veux finir avec le curseur lorsque l'utilisateur s'attend (juste après le numéro 1 récemment ajouté). Il y a quelques sujets sur le réglage du curseur dans TextView
mais c'est UITextField
. J'ai aussi essayé d'attraper selectedTextRange
du champ, qui enregistre la position du curseur correctement mais après l'appel de méthode setText
, cela change automatiquement et l'origine UITextRange
est perdue (changée en courant). j'espère que mon explication est claire.
Aidez-moi avec ça. je vous remercie beaucoup.
EDIT : enfin, j'ai décidé de changer la fonctionnalité pour changer le format après l'édition complète et fonctionne assez bien. Je l'ai fait en ajoutant un sélecteur forControlEvents:UIControlEventEditingDidEnd
.
5 réponses
après le changement de propriété UITextField.text
, toute référence antérieure aux objets UITextPosition
ou UITextRange
qui étaient associés à l'ancien texte sera définie à nil après que vous aurez défini la propriété text. Vous devez stocker ce que le décalage de texte sera après la manipulation sera avant que vous définissiez la propriété de texte.
cela a fonctionné pour moi (notez que vous devez tester si cursorOffset est < textField.texte.longueur si vous supprimez des caractères de t dans le exemple ci-dessous):
- (BOOL) textField:(UITextField *) textField shouldChangeCharactersInRange:(NSRange) range replacementString:(NSString *) string
{
UITextPosition *beginning = textField.beginningOfDocument;
UITextPosition *start = [textField positionFromPosition:beginning offset:range.location];
UITextPosition *end = [textField positionFromPosition:start offset:range.length];
UITextRange *textRange = [textField textRangeFromPosition:start toPosition:end];
// this will be the new cursor location after insert/paste/typing
NSInteger cursorOffset = [textField offsetFromPosition:beginning toPosition:start] + string.length;
// now apply the text changes that were typed or pasted in to the text field
[textField replaceRange:textRange withText:string];
// now go modify the text in interesting ways doing our post processing of what was typed...
NSMutableString *t = [textField.text mutableCopy];
t = [t upperCaseString];
// ... etc
// now update the text field and reposition the cursor afterwards
textField.text = t;
UITextPosition *newCursorPosition = [textField positionFromPosition:textField.beginningOfDocument offset:cursorOffset];
UITextRange *newSelectedRange = [textField textRangeFromPosition:newCursorPosition toPosition:newCursorPosition];
[textField setSelectedTextRange:newSelectedRange];
return NO;
}
et voici la version swift:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let beginning = textField.beginningOfDocument
let start = textField.positionFromPosition(beginning, offset:range.location)
let end = textField.positionFromPosition(start!, offset:range.length)
let textRange = textField.textRangeFromPosition(start!, toPosition:end!)
let cursorOffset = textField.offsetFromPosition(beginning, toPosition:start!) + string.characters.count
// just used same text, use whatever you want :)
textField.text = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
let newCursorPosition = textField.positionFromPosition(textField.beginningOfDocument, offset:cursorOffset)
let newSelectedRange = textField.textRangeFromPosition(newCursorPosition!, toPosition:newCursorPosition!)
textField.selectedTextRange = newSelectedRange
return false
}
Voici une version swift 3
extension UITextField {
func setCursor(position: Int) {
let position = self.position(from: beginningOfDocument, offset: position)!
selectedTextRange = textRange(from: position, to: position)
}
}
mettre en œuvre le code décrit dans cette réponse: déplacer le curseur au début de UITextField
NSRange beginningRange = NSMakeRange(0, 0);
NSRange currentRange = [textField selectedRange];
if(!NSEqualRanges(beginningRange, currentRange))
{
[textField setSelectedRange:beginningRange];
}
EDIT: à Partir de cette réponse , il semble que vous pouvez simplement utiliser ce code avec votre UITextField si vous utilisez iOS 5 ou supérieur. Sinon, vous devez utiliser UITextView à la place.
ce qui a réellement fonctionné pour moi était très simple, vient d'utiliser l'expédition principale async:
DispatchQueue.main.async(execute: {
textField.selectedTextRange = textField.textRange(from: start, to: end)
})