Отримання та встановлення положення курсору 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.