You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift UIKit多UITextField正则校验异常问题及代码修正请求

问题排查与代码修正

核心问题分析

  1. 字段标识重复/为空:如果多个UITextField的paymentParametrName为空或重复,会导致validationResults中不同输入框的校验结果被覆盖,requiredFields也无法正确区分所有必填字段,最终误判allFieldsValid。
  2. 未初始化必填字段的校验状态:只有被编辑过的字段才会存入validationResults,未编辑的必填字段在字典中无对应值,此时validationResults[field] != true会被判定为无效,但如果paymentParametrName重复,会导致未编辑字段被“忽略”。
  3. 正则校验的冗余判断:原代码在textField代理方法中单独判断空正则,逻辑分散,可整合到校验函数中。

修正后的代码

// 移除可选类型,用Bool默认值更清晰
var regexValidate: Bool = false
// 提前初始化所有必填字段的校验状态为false(需在视图加载时传入所有必填的paymentParametrName)
var validationResults: [String: Bool] = [:]
var allFieldsValid: Bool = false
// 建议在视图初始化时传入所有必填字段名称,避免动态插入导致的遗漏
var requiredFields: Set<String> = []

// 新增初始化方法,提前设置必填字段的校验状态
func setupRequiredFields(_ fields: Set<String>) {
    requiredFields = fields
    fields.forEach { validationResults[$0] = false }
}

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let regexPattern = regex, let fieldName = paymentParametrName, !fieldName.isEmpty else {
        // 无正则或字段名无效时,直接返回true(可按需调整)
        return true
    }
    
    let prospectiveText = (textField.text as NSString?)?.replacingCharacters(in: range, with: string) ?? string
    // 调用整合后的正则校验函数
    regexValidate = regexValidate(prospectiveText, withPattern: regexPattern)
    
    // 更新当前字段的校验结果
    validationResults[fieldName] = regexValidate
    
    // 重新判断所有字段是否有效
    allFieldsValid = checkAllFieldsValid()
    
    print("当前输入框校验结果: \(regexValidate)")
    print("所有输入框整体校验结果: \(allFieldsValid)")
    
    return true
}

private func regexValidate(_ text: String, withPattern pattern: String) -> Bool {
    // 空正则直接返回true
    guard !pattern.isEmpty else {
        return true
    }
    
    guard let regex = try? NSRegularExpression(pattern: pattern) else {
        // 正则格式错误时返回false
        return false
    }
    
    let range = NSRange(location: 0, length: text.utf16.count)
    let matches = regex.matches(in: text, options: [], range: range)
    // 匹配整个文本内容才算有效
    return matches.count == 1 && matches.first?.range == range
}

private func checkAllFieldsValid() -> Bool {
    // 遍历所有必填字段,确保每个字段的校验结果都是true
    for field in requiredFields {
        guard let isValid = validationResults[field], isValid else {
            return false
        }
    }
    // 必填字段非空且全部有效时返回true
    return !requiredFields.isEmpty
}

关键修正点说明

  • 提前初始化必填字段:新增setupRequiredFields方法,在视图加载时传入所有必填的paymentParametrName,并将这些字段的校验状态初始化为false,确保未编辑的必填字段也会被纳入校验范围。
  • 字段名非空校验:在textField代理方法中增加fieldName非空判断,避免空字符串作为key导致的结果覆盖。
  • 整合正则校验逻辑:将空正则的判断移到regexValidate函数中,让逻辑更集中。
  • 严格校验字段状态:在checkAllFieldsValid中,确保每个必填字段都存在有效的校验结果且为true,避免因字典中无对应值导致的误判。

使用注意事项

  1. 确保每个UITextField对应的paymentParametrName是唯一且非空的,这是正确区分不同输入框的基础。
  2. 在视图控制器初始化单元格时,调用setupRequiredFields传入所有必填字段的名称集合,例如:
    cell.setupRequiredFields(["phone", "email", "password"])
    

内容的提问来源于stack exchange,提问作者Albert Asadov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:22:31