Swift - 强制 UITextview 仅小写

Swift -Force UITextview Lowercase Only

要强制 UITextfield 仅使用小写字母,我执行以下操作:

lazy var myTextField: UITextField = {
    let textField = UITextField()
    textField.addTarget(self, action: #selector(forceLettersLowercased(_ :)), for: .editingChanged)
    return textField
}()

@objc func forceLettersLowercased(_ sender: UITextField) {
    sender.text = sender.text?.lowercased()
}

如何使用 UITextView 实现相同的目的?

lazy var myTextView: UITextView = {
    let textView = UITextView()
    return textView
}()

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
      
    let textLowerCased = text.lowercased()

    textView.text = (textView.text as NSString).replacingCharacters(in: range, with: textLowerCased)

    let numberOfChars = textView.text.count
    
    return numberOfChars <= 200
}

我总是收到双字母,比如当我输入字母时 'W' 我得到一个小字母和一个大写字母,然后当我按退格键时我得到:[__NSCFString replaceCharactersInRange:withString:]: Range or index out of bounds

而不是 shouldChangeTextIn,使用 textViewDidChange

extension ViewController: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        textView.text = textView.text.lowercased()
    }
}

结果:

您重写了错误的委托方法。 shouldChangeTextIn,顾名思义,是一个委托方法,询问您给定范围 中的文本是否应该 进行更改。你应该使用这个方法来,例如防止用户输入某些字符。

它恰好在文本视图的文本更改时被调用,但这并不意味着您应该使用它来检测文本视图中正在更改的文本,因为该方法将被调用 before 文本被更改,这是有道理的:它会在实际更改之前询问您是否应该更改文本。这就是为什么有两个Ws。第一个小写 w 来自您设置文本视图的文本,第二个大写 W 来自用户实际键入它。

应该实现的委托方法是:

func textViewDidChange(_ textView: UITextView)

这个实际上是在文本更改后调用的。在这里,您可以执行与 UITextField:

相同的操作
textView.text = textView.text?.lowercased()

您似乎也将文本视图的最大长度限制为 200 个字符。该功能应保留在 shouldChangeTextIn 中。如果您不确定,请参阅 this post 了解如何执行此操作。