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

标签 ios uitextview ios13 capitalization iphone-softkeyboard

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

我在 Xcode 11 中创建了一个小示例项目来解释这个问题。该项目针对 iOS 13。我正在运行 iOS 13.1.2 (17A860) 的 iPhone 8 上进行测试。该项目包含一个带有 TextView 的简单 View Controller 。 TextView 有 autoCapitalizationType作为“句子”。然后我实现了委托(delegate)方法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  
    }  
}  

这是整个代码,除了 Storyboard和其他项目文件。正如您在上面看到的,我只是将用户输入的完全相同的文本手动设置到 textview 中,然后返回 false。但是当我输入时,第一个字符会被添加到大写字母中。第二个字符正确地以小写字母添加。从第三个字符开始,一切都大写。此外,在键入每个字符后,键盘切换按钮会自动被选中。附上截图。

enter image description here

其他一些重要的点。
  • 仅当 autocapitalizationType 为
    “句子”,不适用于“单词”、“无”等其他值。
  • 我尝试在代码和 Storyboard 中设置 autocapitalizationType,
    结果相同。
  • 如果我不实现shouldChangeTextInRange 方法,问题就不是
    转载。如果我从此方法返回 true,则问题不是
    转载。由于我需要在这个方法中做一些处理,所以我
    需要返回false。
  • 尚未在 iOS 13 之前的设备上自行复制,尽管用户
    在 iOS 12.4.1 上报告了这一点(目前未经验证)。

  • 任何人都可以为此问题提出修复/解决方法吗?

    最佳答案

    尝试在主循环中安排这个赋值语句:

        textView.text = newString
    

    变成:

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

    这对我来说成功地解决了一个类似的问题,即句子的前两个字母被大写。我最好的猜测是 didSet 背后的逻辑UITextView 的 text 属性的监听器以立即同步触发委托(delegate)的方式更改。在主队列上异步调度分配强制/保证委托(delegate)在第二次被解雇之前返回。

    关于ios - 在 shouldChangeTextInRange 方法中返回 false 自动将所有字母大写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58425591/

    相关文章:

    iphone - iOS上UITextView中两行之间的前导或垂直距离

    swift - 为什么我在 Xcode 11 Beta 5 中使用 ForEach 时会出错?

    iOS 13 更新在第一次显示时破坏了我的应用程序的键盘

    ios - 当 UNNotificationExtensionUserInteractionEnabled 为真时,如何从 UNNotificationContentExtension 触发 didReceiveRemoteNotification

    ios - 无法点击 UITableView 中的最后一个单元格(仅在模拟器 4 中)

    swift - 如何让 UIScrollView 滚动其中的所有内容

    ios - UITextView 插入行为 iOS 7 与 iOS 8

    ios - 如何清除 iOS 中特定域的 cookie?

    ios - 创建 300 dpi PDF 上下文

    iOS 13.1 AVAudio 播放器崩溃