Rx Swift:复杂的文本字段验证

Posted

技术标签:

【中文标题】Rx Swift:复杂的文本字段验证【英文标题】:Rx Swift : Complex TextFields Validation 【发布时间】:2017-03-17 14:42:15 【问题描述】:

我是RxSwift 的新手,我发现的所有示例都是处理简单案例。

我正在尝试对我的文本字段进行表单验证。 我的自定义 TextField 类有一个方法 isValid() 和一个 regexpisValid 返回基于 regexp 属性。

到目前为止,我已经写了以下内容:

let valids = [mLastName, mFirstName, mEmailField].map 
    $0.rx.text.map 
        text -> Bool in
        // I want more complex logic here
        // Like return field.isValid()
        return text!.characters.count > 0
    
    

let _ = Observable.combineLatest(valids)  iterator -> Bool in
    return iterator.reduce(true,  $0 && $1 )
.subscribe(onNext:  allValid in
    ///update button according to AllValid
)

有谁知道如何更新代码以基于我的isValid() 方法而不是text!.characters.count 的第一个Observable<Bool>

【问题讨论】:

【参考方案1】:

可能有很多方法可以做到这一点。

您可以在自定义 TextField 类中使用 filter 转换 rx.text Observable:

var isTextValid: Observable<Bool> 
    return rx.text.filter  _ in 
        return self.isValid()
    

然后您可以将所有文本字段中的isTextValidcombineLatest 结合起来。


您还可以从自定义文本字段中提取验证逻辑(也许您甚至根本不需要自定义文本字段)。

好处:

验证可能更容易进行单元测试 您可以轻松地在应用的不同位置重复使用验证(例如,如果您使用过 UITextView)。

验证器类的草案:

class TextValidator 
    var input: Observable<String>
    var regex: NSRegularExpression

    init(input: Observable<String>, regex: NSRegularExpression) 
       self.input = input
       self.regex = regex
    

    func validate() -> Observable<Bool> 
        return input.map  text in 
             //return true if regex matches the text
        
           

那么你可以如下使用它:

let mailValidator = TextValidator(input: mLastName.rx.text, regex: /* actual regex*/)
let firstNameValidator = TextValidator(input: mFirstName.rx.text, regex: ...)



let _ = Observable.combineLatest(mailValidator.validate(), firstName.validate(), ...) 
// and so on

现在,如果您想为验证器编写单元测试(您可能应该这样做),您可以简单地将 Observable.just("Some value") 作为 input 传递给 TextValidator 并验证 validate() 返回的 Observable 做了什么。

【讨论】:

【参考方案2】:

我自己找到了答案。问题出在第一张地图上,我不应该使用匿名参数。

见:

let valids = [mLastName, mFirstName, mEmailField].map  field in
    field.rx.text.map( _ in return field.isValid() )


_ = Observable.combineLatest(valids)  iterator -> Bool in
    return iterator.reduce(true,  return $0 && $1 )
.bindTo(self.mValidateButton.rx.isEnabled)

【讨论】:

你怎么能在其中添加两个字段是否匹配(密码)? @LeeProbert 取决于您是否要在规则一致性之前或之后检查相等性

以上是关于Rx Swift:复杂的文本字段验证的主要内容,如果未能解决你的问题,请参考以下文章

为啥我无法在 Swift 的登录按钮中验证 textFields

有没有一种方法可以使用 swift 在 alertview 内的文本字段中提供验证

Swift UICollectionView 文本字段

Swift 在文本输入期间验证 2 uitextfield 密码

快速验证文本字段 3

如何以不同的方式格式化不同的文本行,从在 AS3 中创建的文本字段,从 txt 文件填充文本?