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

柔情痞子 提交于 2021-02-08 11:54:33

问题


I’m trying to validate a Password Textfield in realtime (Swift 4.2 & Xcode 10.2.1).

My question is how to validate the conditions listed below in UITextField's shouldChangeCharactersInrange method?

  • Minimum 8 characters
  • Maximum 50 characters
  • Minimum 1 alphabet
  • Minimum 1 number
  • No special characters

Also, there will be a gray color tick image on the left side of all 4 validation messages. As long as the condition are not met, image will be gray color tick. If validation succeeds, tick images will turn to green.

When I tap the Confirm button in the screen, I will have to call Set New Password API. I'm thinking about setting a bool isValidationSuccess to true when all the above conditions are met in shouldChangeCharactersInrange method.

On Confirm button tap, api will only be called if isValidationSuccess is true.

This is what I have managed so far. Could you please help me?

// 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
    }

}

回答1:


Use regex for this.

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
    }
}



回答2:


I have created a regex based on the answers provided and it works. Could you guys please validate this.

  • Minimum 8 characters
  • Maximum 50 characters
  • Minimum 1 alphabet
  • Minimum 1 number
  • No special characters

Common 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 Code

// 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
    }

}

EDIT : As there was no other answers and the one above works for the specified conditions, I'm marking my own answer as the accepted one. Just to be clear, I found the solution using the comments of Wiktor Stribiżew



来源:https://stackoverflow.com/questions/57456555/how-to-validate-uitextfield-that-satisfies-5-different-conditions-using-shouldch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!