UITextField:如何对 "Done" 键做出反应并验证输入

UITextField: How to react to the "Done" key and validate the input

我正在尝试调整我的应用程序的一些 login/sign up 要求,因此当用户选择键盘上的 "Done" 按钮时,我想根据是否有他们输入的文本错误。有点像 instagram:

我试图防止在输入的字符串中使用常规字母和数字之外的任何字符,所以我会用这个问题一石二鸟:

1) 我如何以编程方式访问 "Done" 按钮以访问正确的代码,我应该使用什么方法来检测文本字段字符串中字母和数字之外的任何字符的使用?我知道如何呈现警报视图。

对"Done"点击做出反应

您需要实现 textFieldShouldReturn 委托方法。在其中,您可以根据您设置的禁用字符检查文本字段的文本,并且仅在所有字符都有效时才关闭键盘。

func textFieldShouldReturn(textField: UITextField) -> Bool {
    let forbiddenChars = NSCharacterSet(charactersInString: "@(){}[]")
    for c in textField.text.utf16 {
        if forbiddenChars.characterIsMember(c) {
            println("found forbidden character")
            return false
        }
    }
    textField.resignFirstResponder()
    return true
}

处理多个文本字段

如果您有多个文本字段,则需要在每个文本字段上设置 tag 属性,然后在委托方法中根据其值进行操作。下面是根据文本字段的标签选择一组不同的无效字符的示例。

func textFieldShouldReturn(textField: UITextField) -> Bool {
    let forbiddenChars: NSCharacterSet
    if textField.tag == 0 { // e.g. password field
        forbiddenChars = NSCharacterSet(charactersInString: "@(){}[]")
    } else { // tag != 0, e.g. user name field
        forbiddenChars = NSCharacterSet(charactersInString: "*?.<>\")
    }
    ...
}

在实际应用程序中,您当然应该为标签定义常量,而不是使用文字值。

使用白名单进行字符验证

如果你想使用允许字符的白名单而不是黑名单,你只需要翻转条件。

func textFieldShouldReturn(textField: UITextField) -> Bool {
    let allowedChars = NSCharacterSet(charactersInString: "abcdefg...")
    for c in textField.text.utf16 {
        if !allowedChars.characterIsMember(c) {
            println("found forbidden character")
            return false
        }
    }
    textField.resignFirstResponder()
    return true
}

完全拒绝无效字符的输入

如果您想完全拒绝输入无效字符,您需要实施 shouldChangeCharactersInRange 委托方法并从替换字符串中删除任何不需要的字符。

var myTextField: UITextField

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if count(string) == 0 {
        return true
    }

    let forbiddenChars = NSCharacterSet(charactersInString: "@(){}[]")
    var correctedReplacement = ""
    for c in string.utf16 {
        if !forbiddenChars.characterIsMember(c) {
            correctedReplacement += "\(UnicodeScalar(c))"
        }
    }

    if count(correctedReplacement) > 0 {
        myTextField.text = (myTextField.text as NSString).stringByReplacingCharactersInRange(range, withString: correctedReplacement)
    }

    return false
}

限制输入的长度

不幸的是,UITextField class 没有提供内置的方法来设置输入文本的最大长度。如果您想解决这个问题,您需要实施 shouldChangeCharactersInRange 委托方法,并在达到所需的最大长度后立即从替换字符串中删除字符。

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if count(string) == 0 {
        return true
    }

    let maxLength = 10
    var trimmedReplacement = ""
    for c in string {
        if count(textField.text) - range.length + count(trimmedReplacement) >= maxLength {
            break
        }
        trimmedReplacement += "\(c)"
    }

    if count(trimmedReplacement) > 0 {
        myTextField.text = (myTextField.text as NSString).stringByReplacingCharactersInRange(range, withString: trimmedReplacement)
    }

    return false
}