Reputation: 2489
I'm using RxSwift to validate input from user, if everything is valid I want to enable a button and change its color. In my button class I have created Variable<Bool>
:
var valid = Variable(false)
In initWithCoder
I'm doing such thing:
valid.asObservable()
.subscribe(onNext: { [weak self] valid in
self?.isEnabled = valid
self?.titleLabel?.textColor = valid ? .white : .black
})
.addDisposableTo(disposeBag)
I have a method that validates input and returns an Observable<Bool>
called validateDate()
(I won't post it here for brevity):
let dataValid = viewModel.validateData()
dataValid
.bind(to: submitButton.valid)
.addDisposableTo(disposeBag)
The problem is, that although the valid
value in subscription is correct and enabling button works perfectly, setting button's color does not work properly, because it seems like it changes color on next emission, not when valid became true
.
Am I doing something wrong here? I would be thankful for any help.
Upvotes: 1
Views: 2584
Reputation: 2032
Swift 4, RxCocoa 4 has now dropped UIBindingObserver in favour of Binder
extension Reactive where Base : UIButton {
public var valid : Binder<Bool> {
return Binder(self.base) { button, valid in
button.isEnabled = valid
button.setTitleColor(valid ? .white : .black, for: .normal)
}
}
}
Upvotes: 4
Reputation: 5679
Have you tried setTitleColor
to change button's title color?
You might consider using UIBindingObserver
for UI bindings:
import PlaygroundSupport
import UIKit
import RxSwift
import RxCocoa
extension Reactive where Base: UIButton {
var valid: AnyObserver<Bool> {
return UIBindingObserver(UIElement: base, binding: { (button: UIButton, valid: Bool) in
button.isEnabled = valid
button.setTitleColor(valid ? .white : .black, for: .normal)
}).asObserver()
}
}
let button = UIButton()
button.frame = CGRect(x: 0, y: 0, width: 100, height: 50)
button.backgroundColor = UIColor.orange
button.setTitle("Title", for: .normal)
Observable<Int>
.timer(0, period: 1, scheduler: MainScheduler.instance)
.map({ $0 % 2 == 0})
.bind(to: button.rx.valid)
PlaygroundPage.current.liveView = button
Upvotes: 6