Отримання та встановлення положення курсору UITextField та UITextView у Swift


109

Я експериментував UITextFieldі як працювати з його положенням курсору. Я знайшов ряд відповідей Objective-C, як і в

Але оскільки я працюю зі Swift, я хотів дізнатися, як отримати поточне розташування курсору, а також встановити його у Swift.

Відповідь нижче - результат мого експерименту та перекладу з Objective-C.

Відповіді:


316

Наступний вміст стосується і обох, UITextFieldі UITextView.

Корисна інформація

Сам початок тексту поля тексту:

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)

В одну позицію зліва від поточної позиції курсору

// 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()щоб зосередити увагу на текстовому полі та зробити клавіатуру.

  • Дивіться цю відповідь, як отримати текст у деякому діапазоні.

Дивитися також


Яка мета запускуПозиції? Що ти можеш з цим зробити? Крім того, яка мета може знадобитися для отримання позиції курсору?
Мед

2
@Honey, я використав це ім'я змінної для позначення тут двох різних речей. Перша мала посилання на початок текстового поля. Було б корисно, якби ви хотіли перемістити курсор туди. Другий мав на увазі просити вибраний діапазон тексту. Це корисно, якщо ви хочете скопіювати цей діапазон або встановити на ньому якийсь атрибут.
Сурагч

Чи можна рухати курсор праворуч, поки текстове поле порожнє? Я стежив за вашою відповіддю, але не зміг цього зробити.
Ючель Байрам

1
@yucelbayram, Ви можете розмістити курсор після Н, використовуючи textField.endOfDocument. Ви також можете використовувати підкреслення або пробіли для представлення пропущених літер.
Сурагч

1
@ArielSD, вибачте, я над цим не працював деякий час. Я не можу згадати.
Сурагч

42

у моєму випадку мені довелося використовувати DispatchQueue:

func textViewDidBeginEditing(_ textView: UITextView) {

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

більше нічого з цього та інших ниток не працювало.

PS: Я двічі перевірив, на якому потоці працює textViewDidBeginEditing, і це був головний потік, як повинен працювати весь інтерфейс користувача, так що не впевнений, чому мала ця затримка використання main.asynch.


2
Це не затримка, а наступний цикл запуску. Швидше за все, вибраний діапазон текстового поля модифікується тією ж функцією, що і викликала textViewDidBeginEditing. Отже, розмістивши його на черзі, це станеться після того, як абонент закінчить.
Михайло Озерянський

@MichaelOzeryansky Так, я теж так думаю. Але тут виникає запитання - ЯКІ це правильний метод встановлення положення курсору вручну?
timetowonder

це рішення
вирішило і

1

Для встановлення позиції курсора у вашій точці:

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

Для скидання положення курсору:

textView.endFloatingCursor()

Примітка . Цей приклад працює як у Textview, так і в Textfield.


Плаваючий курсор @Suragch - це один із способів встановлення місця розташування курсора у textView або textField.
Parth Patel

1
let range = field.selectedTextRange

field.text = "hello world"

field.selectedTextRange = range 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.