任何人都可以帮助我:我需要为输入号码实现UITextField
。此数字应始终为十进制格式,包含4个位置,例如12.3456或12.3400。
所以我创建了NSNumberFormatter
,帮助我得到小数位。
我在
中设置UITextField
值
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
方法。
我处理输入,使用格式化程序,最后调用[textField setText: myFormattedValue];
这样可以正常工作但是这个调用也会将光标移动到我的字段的末尾。这是不需要的。例如。我的字段中有12.3400,光标位于最开头,用户类型编号为1.结果值为112.3400,但光标在末尾移动。我希望在用户期望时(在最近添加的数字1之后)以光标结束。有一些关于在TextView
中设置光标的主题,但这是UITextField
。我还尝试捕获字段的selectedTextRange
,这会正确保存光标位置,但在setText
方法调用之后,这会自动更改并且原点UITextRange
将丢失(更改为当前)。希望我的解释清楚。
请帮帮我。非常感谢你。
编辑:最后,我决定在整个编辑后将功能切换为更改格式并且工作得很好。我是通过添加选择器forControlEvents:UIControlEventEditingDidEnd
来完成的。
答案 0 :(得分:41)
更改UITextField.text
属性后,在设置text属性后,与旧文本关联的任何先前对UITextPosition
或UITextRange
对象的引用都将设置为nil。在设置文本属性之前,您需要存储操作之后的文本偏移量。
这对我有用(注意,如果从下面的示例中删除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;
}
答案 1 :(得分:3)
这是快速版本:
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
}
答案 2 :(得分:3)
这是一个快速的3版本
extension UITextField {
func setCursor(position: Int) {
let position = self.position(from: beginningOfDocument, offset: position)!
selectedTextRange = textRange(from: position, to: position)
}
}
答案 3 :(得分:2)
实施此答案中描述的代码:Moving the cursor to the beginning of UITextField
NSRange beginningRange = NSMakeRange(0, 0);
NSRange currentRange = [textField selectedRange];
if(!NSEqualRanges(beginningRange, currentRange))
{
[textField setSelectedRange:beginningRange];
}
编辑:this answer,如果您使用的是iOS 5或更高版本,您可以在UITextField中使用此代码。否则,您需要使用UITextView。
答案 4 :(得分:0)
实际上对我有用的非常简单,只是使用了调度主异步:
DispatchQueue.main.async(execute: {
textField.selectedTextRange = textField.textRange(from: start, to: end)
})
答案 5 :(得分:0)
快速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)
}
}