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 .

26
demandé sur Sujay 2012-06-22 18:06:05

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;
}
40
répondu JasonD 2013-09-27 13:14:00

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
}
3
répondu ergunkocak 2015-11-25 15:44:54

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)
    }
}
3
répondu Jeremy Piednoel 2016-12-07 17:12:44

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.

2
répondu gtmtg 2017-05-23 11:33:14

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)
})
0
répondu Everton Cunha 2017-10-23 13:41:42