Возврат false в методе shouldChangeTextInRange, автоматически использующем заглавные буквы - PullRequest
5 голосов
/ 17 октября 2019

Я вижу странную проблему с UITextView в последних версиях iOS. Согласно моему текущему пониманию, это происходит только в iOS 13. Один из моих пользователей сообщил об этом на iOS 12.4.1, хотя я не могу воспроизвести это на любых устройствах до iOS 13.

Я создалНебольшой пример проекта в Xcode 11, чтобы объяснить проблему. Проект ориентирован на iOS 13. Я тестирую на iPhone 8 под управлением iOS 13.1.2 (17A860). Проект содержит простой контроллер представления с textview. TextView имеет autoCapitalizationType как «предложения». Затем я реализовал метод делегата shouldChangeTextInRange метод. См. Код ниже

class ViewController: UIViewController {  
    @IBOutlet weak var textView: UITextView!  
    override func viewDidLoad() {  
        super.viewDidLoad()  
        self.textView.delegate = self  
        self.textView.autocapitalizationType = .sentences  
    }  
}  
  
extension ViewController: UITextViewDelegate {  
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange,
      replacementText text: String) -> Bool {  
        //I wanted to do some other modifications here, but for now just
        //setting the user typed text manually and returning false  
        if let oldString = textView.text {  
            let newString = oldString.replacingCharacters(in: Range(range, in: oldString)!,  
                                                          with: text)  
            textView.text = newString  
        }  
        return false  
    }  
}  

Это весь код, кроме раскадровки и других файлов проекта. Как вы можете видеть выше, я просто устанавливаю точно такой же текст, который пользователь вводил в текстовое представление вручную, а затем возвращаю false. Но когда я печатаю, первый символ добавляется заглавными буквами, как и должно быть. Второй символ правильно добавляется в маленькой букве. Начиная с третьего символа, все в заглавных буквах. Кроме того, кнопка переключения клавиатуры автоматически выбирается после ввода каждого символа. Снимок экрана прилагается.

enter image description here

Некоторые другие важные моменты.

  1. Эта проблема возникает, только если autocapitalizationType равен "предложениям", но не для других значений, таких как" words "," none ".
  2. Я попытался установить autocapitalizationType в коде и в раскадровке, с одинаковыми результатами.
  3. Если я не реализую метод shouldChangeTextInRange, вопрос не воспроизводится. Если я верну true из этого метода, проблема не будет воспроизведена. Поскольку мне нужно выполнить некоторую обработку в этом методе, мне нужно вернуть false.
  4. И все же воспроизвести самостоятельно на устройстве, предшествующем iOS 13, хотя пользователь сообщил об этом на iOS 12.4.1 (пока не проверено).

Кто-нибудь может предложить исправление / решение этой проблемы?

Ответы [ 2 ]

3 голосов
/ 23 октября 2019

Лучший обходной путь, который я нашел на данный момент, - это вместо этого выполнить обработку в textViewDidChange.

Ошибка также обсуждается здесь: Форум разработчиков Apple

0 голосов
/ 06 ноября 2019

Попробуйте составить расписание этого оператора присваивания в основном цикле:

    textView.text = newString

становится:

    DispatchQueue.main.async {
        textView.text = newString
    }

Это успешно обошло для меня похожую проблему, когда первые две буквы предложениябыли капитализированы. Мое предположение заключается в том, что логика прослушивателя didSet для текстового свойства UITextView изменилась таким образом, что немедленно запускает делегат синхронно. Асинхронное планирование назначения в основной очереди заставляет / гарантирует возврат делегата до его второго запуска.

...