SwiftでのUITextFieldおよびUITextViewのカーソル位置の取得と設定


109

私はこれまでUITextFieldカーソルの位置を試し、どのように操作するかを試してきました。私は次のように、Objective-Cの関係をいくつか見つけました

しかし、私はSwiftを使用しているので、現在のカーソル位置を取得してSwiftで設定する方法を学びたかったのです。

以下の答えは、私の実験とObjective-Cからの翻訳の結果です。

回答:


316

以下の内容は、両方に適用されますUITextFieldUITextView

有用な情報

テキストフィールドテキストの最初の部分:

let startPosition: UITextPosition = textField.beginningOfDocument

テキストフィールドテキストの最後:

let endPosition: UITextPosition = textField.endOfDocument

現在選択されている範囲:

let selectedRange: UITextRange? = textField.selectedTextRange

カーソル位置を取得する

if let selectedRange = textField.selectedTextRange {

    let cursorPosition = textField.offset(from: textField.beginningOfDocument, to: selectedRange.start)

    print("\(cursorPosition)")
}

カーソル位置を設定する

位置を設定するために、これらすべてのメソッドは実際には同じ開始値と終了値で範囲を設定しています。

最初に

let newPosition = textField.beginningOfDocument
textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)

最後まで

let newPosition = textField.endOfDocument
textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)

現在のカーソル位置の左側の1つの位置

// only if there is a currently selected range
if let selectedRange = textField.selectedTextRange {

    // and only if the new position is valid
    if let newPosition = textField.position(from: selectedRange.start, offset: -1) {

        // set the new position
        textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)
    }
}

任意の位置へ

最初から始めて、5文字右に移動します。

let arbitraryValue: Int = 5
if let newPosition = textField.position(from: textField.beginningOfDocument, offset: arbitraryValue) {

    textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)
}

関連した

すべてのテキストを選択

textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)

テキストの範囲を選択

// Range: 3 to 7
let startPosition = textField.position(from: textField.beginningOfDocument, offset: 3)
let endPosition = textField.position(from: textField.beginningOfDocument, offset: 7)

if startPosition != nil && endPosition != nil {
    textField.selectedTextRange = textField.textRange(from: startPosition!, to: endPosition!)
}

現在のカーソル位置にテキストを挿入する

textField.insertText("Hello")

ノート

  • 使用textField.becomeFirstResponder()テキストフィールドにフォーカスを与え、キーボードが表示されるようにします。

  • ある範囲でテキストを取得する方法については、この回答を参照してください。

こちらもご覧ください


startPositionの目的は何ですか?それで何ができますか?また、カーソル位置を取得する必要があるかもしれない目的は何ですか?
ハニー

2
@ハニー、私はその変数名を使用して、ここで2つの異なるものを参照しました。1つ目は、テキストフィールドの先頭を参照することでした。そこにカーソルを移動したい場合に便利です。2つ目は、選択した範囲のテキストの物乞いについて言及することでした。その範囲をコピーしたり、属性を設定したりする場合に便利です。
Suragch 2016

テキストフィールドが空のときにカーソルを右に移動するものはありますか?私はあなたの答えに従いましたが、私はそれを作ることができませんでした。
Yucel Bayram 2017

1
@yucelbayram、を使用してHの後にカーソルを置くことができますtextField.endOfDocument。アンダースコアまたはスペースを使用して、不足している文字を表すこともできます。
Suragch 2017年

1
@ArielSD、申し訳ありませんが、しばらくこれに取り組んでいません。思い出せない。
Suragch

42

私の場合、DispatchQueueを使用する必要がありました。

func textViewDidBeginEditing(_ textView: UITextView) {

   DispatchQueue.main.async{
      textField.selectedTextRange = ...
   }
}

これと他のスレッドからは何も機能しませんでした。

PS:すべてのUIを実行する必要があるので、textViewDidBeginEditingが実行されているスレッドとメインスレッドをダブルチェックしました。


2
これは遅延ではなく、次の実行ループです。ほとんどの場合、テキストフィールドの選択範囲は、を呼び出したのと同じ関数によって変更されていtextViewDidBeginEditingます。したがって、それをキューに入れることにより、発信者が終了した後に発生します。
Michael Ozeryansky

@MichaelOzeryanskyええ、私もそう思います。しかし、これは疑問を投げかけます—カーソル位置を手動で設定するための正しい方法は何ですか?
timetowonder

私の場合もこのソリューションを使用しました
服部半蔵

1

ポイントにカーソル位置を設定するには:

textView.beginFloatingCursor(at: CGPoint(x: 10.0, y: 10.0))

カーソル位置をリセットする場合:

textView.endFloatingCursor()

:この例は、TextviewとTextfieldの両方で機能します。


@Suragch Floating Cursorは、textViewまたはtextFieldでカーソルの位置を設定する1つの方法です。
Parth Patel

1
let range = field.selectedTextRange

field.text = "hello world"

field.selectedTextRange = range 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.