Rxswift验证OTP字段和确认OTP字段上按钮单击



我是RxSwift的新手,想在我的项目中实现一个功能。我必须验证2个字段,OTP和确认OTP使用输入/输出MVVM使用RxSwift提交点击。

Case1:如果任何文本字段为空,提交按钮应该被禁用,所以如果用户开始输入第一个文本字段,提交按钮将被启用(对于确认OTP文本字段也是如此)

Case2:在提交点击我需要验证文本字段是否为空,并在屏幕上显示错误,另外,如果两个文本字段的值不匹配,它将显示错误提交按钮点击。


let otpChangedText = BehaviorSubject<String>(value:"")
let confirmOtpChangedText = BehaviorSubject<String>(value:"")
let submitButtonTapped = PublishSubject<Void>()
let otp1Validation =  otpChangedText.skipWhile { $0.isEmpty}.map {Validator.isEmpty(string: $0)}
let isValidOtp =  otp1Validation.asDriver(onErrorJustReturn:false)
outputs = Outputs (isValidOTP: isValidOtp)

我已经实现了提交按钮禁用状态,但没有得到任何想法,我应该如何显示屏幕上的错误,如果任何字段是空的,如果两个文本字段的值不匹配。

请引导我。由于

作为题外话,从《rx入门》一书中:

受试者提供了一种方便的方法来检查Rx,但不建议日常使用。

你不应该把所有这些主题都放在一起…


首先让我们创建业务规则:

// Case 1
func eitherFilled(first: String?, second: String?) -> Bool {
first != nil && !first!.isEmpty || second != nil && !second!.isEmpty
}
// Case 2
func hasError(first: String?, second: String?) -> Bool {
first == nil || second == nil || first != second
}

您可以独立于Rx或其他任何东西来测试它们,以确保它们是正确的。

现在创建视图模型:

// Case 1
func buttonEnabled(first: Observable<String?>, second: Observable<String?>) -> Observable<Bool> {
Observable.combineLatest(first, second, resultSelector: eitherFilled)
}
// Case 2
func displayError(first: Observable<String?>, second: Observable<String?>) -> Observable<Void> {
Observable.combineLatest(first, second, resultSelector: hasError)
.filter { $0 }
.map { _ in }
}

同样,使用RxTest非常容易测试。

现在你可以把你的视图模型安装到你的视图控制器中,你知道它们是有效的,因为你已经测试过了。(注意:我已经而不是测试了它们。我把它留给你来确保逻辑是正确的。

final class MyViewController: UIViewController {
@IBOutlet weak var otpField: UITextField!
@IBOutlet weak var confirmOtpField: UITextField!
@IBOutlet weak var button: UIButton!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
// Case 1
buttonEnabled(
first: otpField.rx.text.asObservable(),
second: confirmOtpField.rx.text.asObservable()
)
.bind(to: button.rx.isEnabled)
.disposed(by: disposeBag)
// Case 2
displayError(
first: otpField.rx.text.asObservable(),
second: confirmOtpField.rx.text.asObservable()
)
.bind {
finalPresentScene(animated: true) {
UIAlertController(title: "Error", message: "OTP fileds do not match.", preferredStyle: .alert).scene { $0.connectOK() }
}
}
.disposed(by: disposeBag)
}
}

有了以上所有,你有两个模型表示你的业务规则,两个视图模型将这些业务规则转换为视图更新,你的视图控制器用于连接视图模型和视图。

(如果你想了解更多关于我用来呈现警报的代码,请参阅这个GitHub存储库:https://github.com/danielt1263/CLE-Architecture-Tools)

最新更新