I have a textfield that has 2 rules for validation: minimum amount of chars and alphanumerical chars.
I want to be able to represent to the user what he's doing wrong in an error label but the problem is that if I bind the textfield to both rules it can be creepy because once one rule gets approved the ui does a little flickering from the color of the separator for example changing from red to green to red because of the other validation failing.
I'd like to know if there's a way to prioritize one bind over the other. For example, this is what I currently have:
let minimumValidator
= inputField.textField
.rx.text.orEmpty.map { $0.count >= 8 } // Min amount of chars is 8
minimumValidator.bind(to: inputField.rx.minimumChars)
.disposed(by: bag)
let regexValidator
= inputField.textField
.rx.text.orEmpty.map { $0.matches(regex) }
regexValidator.bind(to: inputField.rx.regex)
.disposed(by: bag)
rx.minimumChars and rx.regex are custom binders
var minimumChars: Binder<Bool> {
return Binder(self.base) { control, value in
UIView.animate(withDuration: 0.1) {
if value {
control.separator.backgroundColor = .white
control.errorLabel.isHidden = true
} else {
let error = "Needs more characters"
control.separator.backgroundColor = .red
control.errorLabel.text = error
control.errorLabel.isHidden = false
}
}
}
}
So my idea is to prioritize idk... let's say alphanumerical validation - so it would show error from minimum char till alphanumerical error came up, so till the user resolved the alphanumerical validation it would ignore the other stream from minimum amount of chars. I'm pretty sure i'm missing some combination of combineLatest with merge or idk.
Make a single Binder that uses a custom enum
enum Validation {
case valid
case minimumChars
case alphaNumeric
}
And then have each validator return a value of this enum. Then combineLatest the two validators and map the result to a single Validation and bind.
Something like
Observable.combineLatest(minimumValidator, regexValidator) { v1, v2 in
// if v1 is not valid return it. Otherwise return v2
}