web-dev-qa-db-ja.com

UITextFieldでのカーソル位置の制御

変更通知ハンドラー内のテキストを変更することにより、フォーマットを強制しているUITextFieldがあります。これはうまく機能しますが(リエントラントの問題を解決したら)、もう1つ厄介な問題が残ります。ユーザーがカーソルを文字列の末尾以外の場所に移動すると、書式設定の変更によりカーソルが文字列の末尾に移動します。これは、ユーザーが一度に複数の文字をテキストフィールドの中央に挿入できないことを意味します。 UITextFieldのカーソル位置を覚えてからリセットする方法はありますか?

47
Jeremy

UITextFieldでのカーソル位置の制御は、入力ボックスと位置の計算に非常に多くの抽象化が関係しているため、複雑です。しかし、それは確かに可能です。メンバー関数setSelectedTextRangeを使用できます。

[input setSelectedTextRange:[input textRangeFromPosition:start toPosition:end]];

以下は、範囲を取り、その範囲内のテキストを選択する関数です。特定のインデックスにカーソルを置きたい場合は、長さ0の範囲を使用します。

+ (void)selectTextForInput:(UITextField *)input atRange:(NSRange)range {
    UITextPosition *start = [input positionFromPosition:[input beginningOfDocument] 
                                                 offset:range.location];
    UITextPosition *end = [input positionFromPosition:start
                                               offset:range.length];
    [input setSelectedTextRange:[input textRangeFromPosition:start toPosition:end]];
}

たとえば、UITextField idxinputにカーソルを置くには:

    [Helpers selectTextForInput:input 
                        atRange:NSMakeRange(idx, 0)];
66
Chris R

インデックスに配置するのに便利です(Swift 3)

private func setCursorPosition(input: UITextField, position: Int) {
    let position = input.position(from: input.beginningOfDocument, offset: position)!
    input.selectedTextRange = input.textRange(from: position, to: position)
}
4
George Muntean

私はついにこの問題の解決策を見つけました!必要なテキストをシステムのペーストボードに挿入し、現在のカーソル位置に貼り付けることができます。

[myTextField paste:self]  

この人のブログで解決策を見つけました。
http://dev.ragfield.com/2009/09/insert-text-at-current-cursor-location.html

貼り付け機能はOS V3.0固有ですが、私はそれをテストしましたが、カスタムキーボードでうまく機能します。

この解決策を採用する場合は、おそらくユーザーの既存のクリップボードの内容を保存し、すぐに復元する必要があります。

3
Dan J

Swift @Chris Rのバージョンです。– Swift3用に更新

private func selectTextForInput(input: UITextField, range: NSRange) {
    let start: UITextPosition = input.position(from: input.beginningOfDocument, offset: range.location)!
    let end: UITextPosition = input.position(from: start, offset: range.length)!
    input.selectedTextRange = input.textRange(from: start, to: end)
}
2
gabuchan

このUITextFieldカテゴリーを使用して、カーソル位置を取得および設定してください。

@interface UITextField (CursorPosition)

@property (nonatomic) NSInteger cursorPosition;

@end

@implementation UITextField (CursorPosition)

- (NSInteger)cursorPosition
{
    UITextRange *selectedRange = self.selectedTextRange;
    UITextPosition *textPosition = selectedRange.start;
    return [self offsetFromPosition:self.beginningOfDocument toPosition:textPosition];
}

- (void)setCursorPosition:(NSInteger)position
{
    UITextPosition *textPosition = [self positionFromPosition:self.beginningOfDocument offset:position];
    [self setSelectedTextRange:[self textRangeFromPosition:textPosition toPosition:textPosition]];
}

@end
1
Pavel Alexeev

UITextFieldの特定の場所にカーソルを置く方法はないと思います(非常にトリッキーになり、タッチイベントをシミュレートしない限り)。代わりに、ユーザーがfinishedテキストの編集(textFieldShouldEndEditing:)エントリが正しくない場合は、テキストフィールドの編集を終了しないでください。

0
pix0r