在shouldChangeTextInRange方法中返回false将自动大写所有字母

Kri*_*dra 5 capitalization uitextview ios iphone-softkeyboard ios13

我在最新的iOS版本中看到UITextView的奇怪问题。根据我目前的理解,它仅在iOS 13中发生。我的一个用户在iOS 12.4.1上报告了此问题,尽管我无法在任何iOS 13之前的设备上重现此问题。

我已经在Xcode 11中创建了一个小示例项目来解释该问题。该项目面向iOS13。我正在运行iOS 13.1.2(17A860)的iPhone 8上进行测试。该项目包含一个带有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  
    }  
}  
Run Code Online (Sandbox Code Playgroud)

这是整个代码,除了情节提要和其他项目文件。如您在上面看到的,我只是将用户输入的完全相同的文本手动设置到textview中,然后返回false。但是,当我键入内容时,第一个字符会按原样添加在大写字母中。第二个字符正确以小写字母添加。从第三个角色开始,所有内容均显示上限。此外,键入每个字符后,键盘移位按钮会自动被选择。附有屏幕截图。

在此处输入图片说明

其他一些要点。

  1. 仅当autocapitalizationType为“ sentences”时,才会发生此问题,而对于其他值,例如“ words”,“ none”,则不会发生。
  2. 我尝试在代码和情节提要中设置autocapitalizationType,结果相同。
  3. 如果我没有实现shouldChangeTextInRange方法,则不会重现问题。如果我从此方法返回true,则不会重现问题。由于需要使用此方法进行一些处理,因此需要返回false。
  4. 尽管用户在iOS 12.4.1上进行了报告(目前尚未验证),但仍可以在iOS 13之前的设备上自行复制。

谁能为此问题提出修复/解决方法?  

Aus*_*tin 9

尝试在主循环中调度此赋值语句:

    textView.text = newString
Run Code Online (Sandbox Code Playgroud)

变成:

    DispatchQueue.main.async {
        textView.text = newString
    }
Run Code Online (Sandbox Code Playgroud)

这对我来说成功地解决了类似的问题,其中句子的前两个字母大写。我最好的猜测是didSetUITextView 的文本属性的侦听器背后的逻辑以立即同步触发委托的方式更改。在主队列上异步安排分配会强制/保证委托在第二次被解雇之前返回。


Nik*_*laj 7

到目前为止,我发现的最佳解决方法是改为进行处理textViewDidChange

该错误也在此处讨论:Apple developer forum