ios 设置其值后如何在 UITextField 中移动光标
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11157791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to move cursor in UITextField after setting its value
提问by user1135839
can anybody help me with this: i need to implement UITextField
for input number. This number should always be in decimal format with 4 places e.g. 12.3456 or 12.3400.
So I created NSNumberFormatter
that helps me with decimal places.
任何人都可以帮我解决这个问题:我需要实现UITextField
输入号码。此数字应始终为 4 位十进制格式,例如 12.3456 或 12.3400。所以我创建NSNumberFormatter
了帮助我处理小数位的方法。
I am setting the UITextField
value in
我正在设置UITextField
值
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
method.
I proccess input, use formatter and finally call [textField setText: myFormattedValue];
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
方法。我处理输入,使用格式化程序,最后调用[textField setText: myFormattedValue];
This works fine but this call also moves the cursor to the end of my field. That is unwanted. E.g. I have 12.3400 in my field and the cursor is located on the very beginning and user types number 1. The result value is 112.3400 but cursor is moved at the end. I want to end with cursor when the user expects (just after the number 1 recently added). There are some topics about setting cursor in TextView
but this is UITextField
. I also tried to catch selectedTextRange
of the field, which saves the cursor position properly but after setText
method call, this automatically changes and the origin UITextRange
is lost (changed to current). hopefully my explanation is clear.
这工作正常,但此调用还将光标移动到我的字段的末尾。那是不想要的。例如,我的字段中有 12.3400,光标位于最开始处,用户键入数字 1。结果值为 112.3400,但光标在末尾移动。我想在用户期望时以光标结束(就在最近添加的数字 1 之后)。有一些关于设置光标的主题,TextView
但这是UITextField
. 我还尝试捕获selectedTextRange
该字段,它正确保存了光标位置,但是在setText
方法调用之后,这会自动更改并且原点UITextRange
丢失(更改为当前)。希望我的解释是清楚的。
Please, help me with this. thank you very much.
请在这件事上给予我帮助。非常感谢您。
EDIT: Finally, i decided to switch the functionality to changing the format after whole editing and works good enough. I have done it by adding a selector forControlEvents:UIControlEventEditingDidEnd
.
编辑:最后,我决定在整个编辑后将功能切换到更改格式并且效果很好。我通过添加一个选择器来完成它forControlEvents:UIControlEventEditingDidEnd
。
回答by JasonD
After the UITextField.text
property is changed, any previous references to UITextPosition
or UITextRange
objects that were associated with the old text will be set to nil after you set the text property. You need to store what the text offset will be after the manipulation will be BEFORE you set the text property.
后UITextField.text
属性更改,之前的任一引用UITextPosition
或UITextRange
设置text属性后,用旧的文本关联的对象将被设置为零。在设置 text 属性之前,您需要存储操作之后的文本偏移量。
This worked for me (note, you do have to test whether cursorOffset is < textField.text.length if you remove any characters from t in the example below):
这对我有用(注意,如果在下面的示例中从 t 中删除任何字符,则必须测试 cursorOffset 是否为 < textField.text.length ):
- (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;
}
回答by ergunkocak
And here is the swift version :
这是快速版本:
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
}
回答by Jeremy Piednoel
Here is a swift 3 version
这是一个 swift 3 版本
extension UITextField {
func setCursor(position: Int) {
let position = self.position(from: beginningOfDocument, offset: position)!
selectedTextRange = textRange(from: position, to: position)
}
}
回答by gtmtg
Implement the code described in this answer: Moving the cursor to the beginning of UITextField
实现此答案中描述的代码:将光标移动到 UITextField 的开头
NSRange beginningRange = NSMakeRange(0, 0);
NSRange currentRange = [textField selectedRange];
if(!NSEqualRanges(beginningRange, currentRange))
{
[textField setSelectedRange:beginningRange];
}
EDIT:From this answer, it looks like you can just use this code with your UITextField if you're using iOS 5 or above. Otherwise, you need to use a UITextView instead.
编辑:从这个答案来看,如果您使用的是 iOS 5 或更高版本,您似乎可以将此代码与 UITextField 一起使用。否则,您需要改用 UITextView。
回答by Everton Cunha
What actually worked for me was very simple, just used dispatch main async:
实际上对我有用的非常简单,只需使用 dispatch main async:
DispatchQueue.main.async(execute: {
textField.selectedTextRange = textField.textRange(from: start, to: end)
})
回答by Mike Glukhov
Swift X. To prevent from moving cursor from last position.
Swift X. 防止光标从最后一个位置移动。
func textFieldDidChangeSelection(_ textField: UITextField) {
let point = CGPoint(x: bounds.maxX, y: bounds.height / 2)
if let textPosition = textField.closestPosition(to: point) {
textField.selectedTextRange = textField.textRange(from: textPosition, to: textPosition)
}
}