誰かがこれで私を助けることができます:入力番号にUITextField
を実装する必要があります。この数値は常に4桁の10進数形式である必要があります。 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
メソッド呼び出しの後、これは自動的に変更され、Origin UITextRange
が失われます(現在の)。うまくいけば、私の説明は明確です。
これで私を助けてください。どうもありがとうございました。
[〜#〜] edit [〜#〜]:最後に、全体の編集後に機能をフォーマットの変更に切り替えることにし、十分に機能します。セレクタforControlEvents:UIControlEventEditingDidEnd
を追加することでそれを実現しました。
後に UITextField.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;
}
Swift 3バージョン
extension UITextField {
func setCursor(position: Int) {
let position = self.position(from: beginningOfDocument, offset: position)!
selectedTextRange = textRange(from: position, to: position)
}
}
そして、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
}
この回答で説明されているコードを実装します。 ITextFieldの先頭にカーソルを移動
NSRange beginningRange = NSMakeRange(0, 0);
NSRange currentRange = [textField selectedRange];
if(!NSEqualRanges(beginningRange, currentRange))
{
[textField setSelectedRange:beginningRange];
}
EDIT:this answer から、iOS 5を使用している場合、UITextFieldでこのコードを使用できるようです以上。それ以外の場合は、代わりにUITextViewを使用する必要があります。
実際に機能したのは非常にシンプルで、dispatch main asyncを使用しただけです。
DispatchQueue.main.async(execute: {
textField.selectedTextRange = textField.textRange(from: start, to: end)
})
SwiftX。カーソルを最後の位置から移動しないようにします。
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)
}
}