如何使用 shouldChangeCharactersInrange 方法验证满足 5 个不同条件的 UITextfield?
Posted
技术标签:
【中文标题】如何使用 shouldChangeCharactersInrange 方法验证满足 5 个不同条件的 UITextfield?【英文标题】:How to validate UITextfield that satisfies 5 different conditions using shouldChangeCharactersInrange method? 【发布时间】:2019-08-12 06:31:14 【问题描述】:我正在尝试实时验证密码文本字段(Swift 4.2 和 Xcode 10.2.1)。
我的问题是如何验证 UITextField 的 shouldChangeCharactersInrange 方法中列出的条件?
最少 8 个字符 最多 50 个字符 最少 1 个字母 最少 1 个号码 无特殊字符此外,所有 4 条验证消息的左侧都会有一个灰色刻度图像。只要条件不满足,图像就会被灰色打勾。如果验证成功,刻度图像将变为绿色。
当我点击屏幕上的确认按钮时,我将不得不调用设置新密码 API。当在 shouldChangeCharactersInrange 方法中满足上述所有条件时,我正在考虑将 bool isValidationSuccess 设置为 true。
在点击确认按钮时,只有当 isValidationSuccess 为 true 时才会调用 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
【问题讨论】:
如果您的方法返回布尔值,为什么要使用.replacingCharacters
?我想你可以使用range
,比如:return newPasswordTextfield.text.range(of: "^(?=\\D*\\d)(?=\\d*[A-Za-z])[A-Za-z0-9]8,50$", options: .regularExpression) != nil
@WiktorStribiżew:能否验证我找到的解决方案?我已将其添加为答案。
【参考方案1】:
我根据提供的答案创建了一个正则表达式,它可以工作。请你们验证一下。
最少 8 个字符 最多 50 个字符 最少 1 个字母 最少 1 个号码 无特殊字符普通类
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 的 cmets 找到了解决方案
【讨论】:
仅当 isValidPasswordStatus 为 true 时才会调用按钮操作中的 API 调用。 如果您将NSPredicate
与MATCHES
一起使用,则在开始/结束时不需要正则表达式中的锚点。另外,使用对比原理。此外,\d
匹配的次数多于 [0-9]
。使用let passwordRegex = "(?=[^A-Za-z]*[A-Za-z])(?=[^0-9]*[0-9])[A-Za-z0-9]8,50"
@WiktorStribiżew 我已经更新了正则表达式。我还有一个问题。每当特定验证成功时,如何更改 ImageViews 的 isHighlightedvalue?目前,必须传递整个正则表达式才能使“if Common.isValidPassword(updatedText)”条件为真。我的意思是,如果输入单个数字,“minimumNumberValidationImage”应该会突出显示。
然后一步一步地做每个验证,不要使用塞满前瞻的正则表达式。【参考方案2】:
为此使用正则表达式。
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
【讨论】:
我已经修改了你的答案并找到了解决方案。我不明白这种情况是如何运作的。 (如果 passwordTextField.isValidPassword == true)我们必须将密码文本字段文本传递给正则表达式函数并验证该字符串。以上是关于如何使用 shouldChangeCharactersInrange 方法验证满足 5 个不同条件的 UITextfield?的主要内容,如果未能解决你的问题,请参考以下文章