如何使用 shouldChangeCharactersInrange 方法验证满足 5 个不同条件的 UITextfield?

How to validate UITextfield that satisfies 5 different conditions using shouldChangeCharactersInrange method?

我正在尝试实时验证密码文本字段 (Swift 4.2 & Xcode 10.2.1)。

我的问题是如何验证下面在 UITextField 的 shouldChangeCharactersInrange 方法中列出的条件?

此外,所有 4 条验证消息的左侧都会有一个灰色勾号图像。只要不满足条件,图像就会是灰色勾号。如果验证成功,刻度图像将变为绿色。

当我点击屏幕上的“确认”按钮时,我将不得不调用“设置新密码”API。当在 shouldChangeCharactersInrange 方法中满足上述所有条件时,我正在考虑将 bool isValidationSuccess 设置为 true。

点击“确认”按钮时,只有在 isValidationSuccess 为真时才会调用 api。

这就是我到目前为止所管理的。你能帮帮我吗?

// MARK: - TextField delegate methods
extension SetNewPasswordViewController: UITextFieldDelegate {

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{
        let minPasswordLength = 8
        let currentString: NSString = newPasswordTextfield.text! as NSString
        let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString

        if newString.length < minPasswordLength {
            minimumCharacterValidationImage.isHighlighted = false
        } else {
            minimumCharacterValidationImage.isHighlighted = true
        }

        return true
    }

}

为此使用正则表达式。

func isValidPassword() -> Bool {
    let passwordRegex = "^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,50}$"
    return NSPredicate(format: "SELF MATCHES %@", passwordRegex).evaluate(with: self)
}

extension SetNewPasswordViewController: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{
        if textField == passwordTextField {
            if passwordTextField.isValidPassword == true
            {
                return true
            }else{
                return false
            }
        }
        return true
    }
}

我根据所提供的答案创建了一个正则表达式,并且可以正常工作。你们能验证一下吗?

  • 最少 8 个字符
  • 最多 50 个字符
  • 最少 1 个字母表
  • 最少 1 个号码
  • 没有特殊字符

普通Class

class Common: NSObject {

        // MARK: - Password TextField Validations
        static func isValidPassword(_ input: String) -> Bool {
            print("validate Password: \(input)")
            let passwordRegex = "^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,50}$"
            return NSPredicate(format: "SELF MATCHES %@", passwordRegex).evaluate(with: input)
        }
    }

ViewController代码

// MARK: - TextField delegate methods
extension SetNewPasswordViewController: UITextFieldDelegate {

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

            if let text = newPasswordTextfield.text,
                let textRange = Range(range, in: text) {
                let updatedText = text.replacingCharacters(in: textRange,
                                                           with: string)
                if Common.isValidPassword(updatedText) == true {
                    minimumCharacterValidationImage.isHighlighted = true
                    minimumAlphabetValidationImage.isHighlighted = true
                    minimumNumberValidationImage.isHighlighted = true
                    noSpecialCharacterValidationImage.isHighlighted = true
                    minimumCharacterValidationImage.isHighlighted = true
                    confirmButton.backgroundColor = UIColor(red:0, green:0.5, blue:0.54, alpha:1)
                    isValidPasswordStatus = true
                } else {
                    minimumCharacterValidationImage.isHighlighted = false
                    minimumAlphabetValidationImage.isHighlighted = false
                    minimumNumberValidationImage.isHighlighted = false
                    noSpecialCharacterValidationImage.isHighlighted = false
                    confirmButton.backgroundColor = UIColor(red:0.4, green:0.47, blue:0.5, alpha:1)
                    isValidPasswordStatus = false
                }
            }

        }
        return true
    }

}

编辑:由于没有其他答案并且上面的答案适用于指定条件,我将我自己的答案标记为已接受的答案。明确地说,我使用 Wiktor Stribiżew

的评论找到了解决方案