ios - cómo mover el cursor en UITextField después de establecer su valor
nsnumberformatter selectedtext (5)
Aquí hay una versión rápida de 3
extension UITextField {
func setCursor(position: Int) {
let position = self.position(from: beginningOfDocument, offset: position)!
selectedTextRange = textRange(from: position, to: position)
}
}
¿Alguien puede ayudarme con esto? Necesito implementar UITextField
para el número de entrada. Este número siempre debe estar en formato decimal con 4 lugares, por ejemplo, 12.3456 o 12.3400. Así que creé NSNumberFormatter
que me ayuda con decimales.
Estoy configurando el valor de UITextField
en
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
método de -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
. Procuro la entrada, uso el formateador y finalmente llamo [textField setText: myFormattedValue];
Esto funciona bien, pero esta llamada también mueve el cursor al final de mi campo. Eso no es deseado. Por ejemplo, tengo 12.3400 en mi campo y el cursor está ubicado en el principio y el usuario escribe el número 1. El valor del resultado es 112.3400 pero el cursor se mueve al final. Quiero terminar con el cursor cuando el usuario lo espera (justo después del número 1 recientemente agregado). Hay algunos temas sobre la configuración del cursor en TextView
pero esto es UITextField
. También intenté capturar el selectedTextRange
de texto selectedTextRange
del campo, que guarda la posición del cursor correctamente, pero después de la setText
método setText
, esto cambia automáticamente y el origen del UITextRange
se pierde (se cambia a actual). Espero que mi explicación sea clara.
Por favor, ayúdame con esto. muchas gracias.
EDITAR : Finalmente, decidí cambiar la funcionalidad para cambiar el formato después de la edición completa y funciona lo suficientemente bien. Lo he hecho agregando un selector para forControlEvents:UIControlEventEditingDidEnd
.
Después de UITextField.text
propiedad UITextField.text
, cualquier referencia anterior a los objetos UITextPosition
o UITextRange
que se asociaron con el texto antiguo se establecerá en nil después de establecer la propiedad de texto. Debe almacenar lo que será el desplazamiento de texto después de la manipulación ANTES de establecer la propiedad de texto.
Esto funcionó para mí (tenga en cuenta que tiene que probar si cursorOffset es <textField.text.length si elimina cualquier carácter de t en el ejemplo a continuación):
- (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;
}
Implemente el código descrito en esta respuesta: mover el cursor al principio de UITextField
NSRange beginningRange = NSMakeRange(0, 0);
NSRange currentRange = [textField selectedRange];
if(!NSEqualRanges(beginningRange, currentRange))
{
[textField setSelectedRange:beginningRange];
}
EDITAR: De esta respuesta , parece que puede usar este código con su UITextField si está usando iOS 5 o superior. De lo contrario, necesita utilizar un UITextView en su lugar.
Lo que realmente funcionó para mí fue muy simple, solo usé el comando async main:
DispatchQueue.main.async(execute: {
textField.selectedTextRange = textField.textRange(from: start, to: end)
})
Y aquí está la versión rápida:
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
}