UITextView наблюдает за изменениями текста - PullRequest
1 голос
/ 17 июня 2020

Я хочу прослушивать каждое изменение текста в UITextView. Настройка очень тривиальна.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(textViewDidChangeWithNotification(_:)),
        name: UITextView.textDidChangeNotification,
        object: nil
    )
}

@objc private func textViewDidChangeWithNotification(_ notification: Notification) {
     print("Text: \(String(describing: inputTextView.text))")
}

В большинстве случаев он работает нормально, но потом я нашел несколько магов черного ящика UITextInput c.

Шаг 1: «Я» напечатал. В выводе мы видим «I».
Шаг 2: Важный шаг. Выделите весь текст двойным нажатием на поле.
Шаг 3: Выберите «Если» из предложенных слов.

enter image description here

И в выводе отладчика нет «Если». С другой стороны, если курсор будет в конце слова «I», и мы выберем «Если», результаты будут правильными.

enter image description here

Есть ли способ наблюдать ВСЕ изменения текста?

Я могу получить текст, используя:

func textViewDidEndEditing(_ textView: UITextView)

, но мне нужно наблюдать за всеми изменениями в реальном времени. Другой вариант, который я всегда вижу, - это использовать:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool

, но этот метод - плохая практика для наблюдения за изменениями. Если вы вводите два пробела несколько раз, iOS заменит первый пробел точкой и, очевидно, не будет информировать вас об этом действии в этом методе и о множестве других проблем с ним.

Ответы [ 3 ]

2 голосов
/ 19 июня 2020

Хорошо, после долгих исследований я попробовал RxSwift, потому что думал, что наблюдение текста в рамках реактивной парадигмы должно быть успешным в 100% случаев. И это сработало без проблем!

inputTextView.rx.text.subscribe(onNext: { string in
    print("rx: \(string)")
})

Кажется, эти ребята нашли решение.

https://github.com/ReactiveX/RxSwift/blob/master/RxCocoa/iOS/UITextView%2BRx.swift

это решение, которое дает вам информацию обо всех изменениях текста, несмотря на автокоррекцию, выделение текста и т. д. c ..

class ViewController: UIViewController {

    @IBOutlet weak var inputTextView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()
        inputTextView.textStorage.delegate = self
    }
}

extension ViewController: NSTextStorageDelegate {
    func textStorage(_ textStorage: NSTextStorage, didProcessEditing editedMask: NSTextStorage.EditActions, range editedRange: NSRange, changeInLength delta: Int) {
        print("string: \(textStorage.string)")
    }
}
2 голосов
/ 17 июня 2020

Вы можете использовать func textViewDidChangeSelection(_ textView: UITextView), чтобы обнаружить изменение в выборе?

0 голосов
/ 17 июня 2020

Если вы хотите слушать каждое изменение, shouldChangeTextIn - это путь к go. Вы можете написать условия для решения связанных с этим проблем

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...