问题
I have two input fields, one for password and another one to confirm the password. I want to create a custom binder that will allow me to compare the value of both input fields but also validate minimum amount of chars. I had a pretty similar question but not regarding comparing two different fields (Is there some sort of Priority operator on RxSwift?) and based on the answer for that previous question I've been trying to do something like this:
enum PasswordCreateValidation {
case valid
case lessThanMinimum
case confirmationLessThanMinimum
case differentInputs
}
extension Reactive where Base: [InputField] {
var rxPassword: Binder<PasswordCreateValidation> {
return Binder<[InputField]>(self.base) { control, value in
switch value {
case .valid :
control[0].errorLabel.isHidden = true
control[1].errorLabel.isHidden = true
control[0].separator.backgroundColor = .white
control[1].separator.backgroundColor = .white
case .lessThanMinimum:
control[0].errorLabel.isHidden = false
control[0].separator.backgroundColor = .red
control[0].errorLabel.text = "Needs more chars"
case .confirmationLessThanMinimum:
control[1].errorLabel.isHidden = false
control[1].separator.backgroundColor = .red
control[1].errorLabel.text = "Needs more chars"
case .differentInputs:
control[0].errorLabel.isHidden = false
control[0].separator.backgroundColor = .red
control[0].errorLabel.text = "Inputs are not the same"
control[1].errorLabel.isHidden = false
control[1].separator.backgroundColor = .red
control[1].errorLabel.text = "Inputs are not the same"
}
}
}
}
...
private func bind() {
let codeMinimum = codeInputField.textField.rx.text.orEmpty.map { $0.count >= 1 }.skip(2)
codeMinimum.bind(to: codeInputField.rx.nonEmpty).disposed(by: bag)
let minimumAmountPassword = 8
pwdInputField.minimumAmountOfChars = minimumAmountPassword
confirmPwdInputField.minimumAmountOfChars = minimumAmountPassword
let pwdMinimum = pwdInputField.textField
.rx.text.orEmpty.map { $0.count >= minimumAmountPassword }.skip(2)
let confPwdMinimum = confirmPwdInputField.textField
.rx.text.orEmpty.map { $0.count >= minimumAmountPassword }.skip(2)
pwdMinimum.bind(to: pwdInputField.rx.minimumChars).disposed(by: bag)
confPwdMinimum.bind(to: confirmPwdInputField.rx.minimumChars).disposed(by: bag)
let pwdEqualA = pwdInputField.textField.rx.text.orEmpty
.map { $0 == self.confirmPwdInputField.value }.skip(2)
let pwdEqualB = confirmPwdInputField.textField.rx.text.orEmpty
.map { $0 == self.pwdInputField.value }.skip(2)
let equality = Observable.combineLatest(pwdEqualA, pwdEqualB) { $0 && $1 }
let minimum = Observable.combineLatest(pwdMinimum, confPwdMinimum) { $0 && $1 }
let pwdValidation = Observable.combineLatest(equality, minimum) { $0 && $1 }
Observable.combineLatest(pwdValidation, codeMinimum) { $0 && $1 }
.startWith(false)
.bind(to: signInButton.rx.isActive)
.disposed(by: bag)
}
Seems my custom binder is wrong. isn't it allowed to have an array as Base?
回答1:
I’d make a view that has two input fields and use that view as the base
来源:https://stackoverflow.com/questions/59691355/is-possible-to-do-a-custom-binder-on-an-array-of-input-fields-using-rxswift