如何为多个文本字段设置 UITextFieldDelegate?

How to set up UITextFieldDelegate for multiple text fields?

我不能运行这样的代码,怎么了? 它不适用于所有文本字段,而只适用于其中一个。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    let newlenght1 = (textField1.text?.utf16.count)! + string.utf16.count - range.length // I have 3 textfield and I want for all of them same rule
    let newlenght2 = (textField2.text?.utf16.count)! + string.utf16.count - range.length // I have 3 textfield and I want for all of them same rule
    let newlenght3 = (textField3.text?.utf16.count)! + string.utf16.count - range.length // I have 3 textfield and I want for all of them same rule
    let allowedCharacters = "ABCDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ" // I only this charachters // allowed characters
    let characthers = CharacterSet(charactersIn: allowedCharacters)
    let charactersType = CharacterSet(charactersIn: string)
    let finalCharacters = characthers.isSuperset(of: charactersType)
    
    if textField == textField1 && textField == textField2 && textField == textField3 && newlenght1 <= 1 && newlenght2 <= 1 && newlenght3 <= 1 {
        return finalCharacters // but don't work for all textfield ,worked for only 1 textfield
    }else{
        return false
    }   
}

如果您的目标是让所有三个文本字段都遵循相同的规则,请为所有三个文本字段设置 delegateshouldChangeCharactersIn 只需要检查用户当前正在输入的“当前”文本字段。

一个小观察,但我也会避免重复重新创建允许字符的 CharacterSet。您可以简单地将其设为 属性.

将其简化为:

private let allowedCharacters = CharacterSet(charactersIn: "ABCDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ")

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if (textField.text?.count ?? 0) - range.length + string.count > 1 {
        return false
    }

    return allowedCharacters.isSuperset(of: CharacterSet(charactersIn: string.localizedUppercase))
}

如果您希望他们只输入大写字符,我会:

  • 将键盘大小写更改为“所有字符”,这样他们更有可能不输入小写字母:

  • 可选择通过为您的文本字段添加“编辑已更改”操作来更改大小写:

    @IBAction func editingChanged(_ textField: UITextField) {
        textField.text = textField.text?.localizedUppercase
    }
    

    您可能需要试验是否要使用 localizedUppercaseuppercased()uppercased(with:)

    请注意,这种“将整个字符串大写”的逻辑有点草率。如果您在输入中允许使用 multi-character 字符串,您真的会想要捕获光标所在的位置并将其恢复。 (否则,如果用户正在更改 multi-character 字符串的第一个字符,光标将跳到末尾,这可能是一个烦人的用户体验。)例如,一个简单的再现可能是:

    @IBAction func editingChanged(_ textField: UITextField) {
        let range = textField.selectedTextRange
        textField.text = textField.text?.localizedUppercase
        textField.selectedTextRange = range
    }
    

    但是对于您的单个字符输入,上面的简单示例应该足够了。