Это сложно, но вы на правильном пути.
Я также проверяю надежность пароля впоследствии с помощью этого метода
Не ясно, когда вы вызывают isPasswordValid(:)
, но это необходимо сделать после изменения текстового поля, в идеале в функции passwordTextFieldDidChange(:)
.
Бонус: вы можете переместить обновление кнопки «глаз» в отдельную функцию, чтобы улучшить читаемость .
@objc func passwordTextFieldDidChange(_ textField: UITextField) {
self.updateEyeButton(show: !textField.isEmpty)
self.validate(password: textField.text)
}
Существует множество способов выполнить эту задачу sh, но эта задача должна быть достаточно понятной, не стесняйтесь спрашивать, нуждаетесь ли вы в дополнительных разъяснениях.
Вам нужно будет отделить проверку каждого из ваших требований. В вашей текущей функции isPasswordValid(:)
вы проверяете все требования вместе, что делает невозможным определить, какое из них прошло / не выполнено.
Что вы можете сделать, это создать отдельную структуру для проверки требований, в данном случае мы назвали ее PasswordValidator
. Эта структура проверяет, соответствует ли данный пароль вашим требованиям, и если нет, возвращает вам недостающие требования. После того, как у вас есть массив отсутствующих требований, вы можете действовать по каждому из них (в вашем случае изменить значок для каждого из них).
Примерно так (непроверено):
private struct PasswordValidator {
private enum Result {
case valid
case invalid([Validator.Requirement])
}
private enum Requirement: String {
case minimumOneUppercaseOneLowercase = "(?=.*[A-Z]).(?=.*[a-z])"
case minimumOneDigit = "(?=.*[0-9])"
}
static func validate(password: String) -> PasswordValidator.Result {
let missingRequirements = [Requirement]()
if !evaluate(password: password, requirement: .minimumOneUppercaseOneLowercase) {
missingRequirements.append(.minimumOneUppercaseOneLowercase)
}
if !evaluate(password: password, requirement: .minimumOneDigit) {
missingRequirements.append(.minimumOneDigit)
}
if missingRequirements.isEmpty == false {
return .invalid(missingRequirements)
}
return .valid
}
private static func evaluate(password: String, requirement: PasswordValidator.Requirement) -> Bool {
let predicateString = "^\(requirement.rawValue)$"
let passwordTest = NSPredicate(format: "SELF MATCHES %@", predicateString)
return passwordTest.evaluate(with: password)
}
}
Как вы можете видеть, каждое из перечислений PasswordValidator.Requirement
имеет ассоциированное значение, содержащее предикат (очень непроверенный!)
Теперь в вашем контроллере представления вы можете иметь простую функцию для обработки результата проверки (вызывается из Ваша passwordTextFieldDidChange(:)
функция:
private func validate(password: String) {
let validationResult = PasswordValidator.validate(password: password)
switch validationResult {
case .valid:
// All should be checkmarks
// self.updateIcons(missingRequirements: nil)
case .invalid(let missingRequirements):
// Change the icons
// self.updateIcons(missingRequirements: missingRequirements)
}
}