The following code works for me, building on prex's answer. Please feel free to correct or suggest any improvements.
RxSwift/RxCocoa 4.4, iOS 12, Xcode 10
private let _disposeBag = DisposeBag()
let viewModel: ViewModel ...
let switchControl: UIControl ...
let observable = switchControl
.rx.isOn
.changed // We want user-initiated changes only.
.distinctUntilChanged()
.share(replay: 1, scope: .forever)
observable
.subscribe(onNext: { [weak self] value in
self?.viewModel.setSomeOption(value)
})
.disposed(by: _disposeBag)
In this example, we are notified when the user (and only the user) changes the state of the UISwitch. We then update viewModel.
In turn, any observers of the viewModel, will be told of the change of state, allowing them to update UI, etc.
e.g.
class ViewModel
{
private var _someOption = BehaviorRelay(value: false)
func setSomeOption(_ value: Bool) { _someOption.accept(value) }
/// Creates and returns an Observable on the main thread.
func observeSomeOption() -> Observable<Bool>
{
return _someOption
.asObservable()
.observeOn(MainScheduler())
}
}
...
// In viewDidLoad()
self.viewModel
.observeSomeOption()
.subscribe(onNext: { [weak self] value in
self?.switchControl.isOn = value
// could show/hide other UI here.
})
.disposed(by: _disposeBag)
See: https://stackoverflow.com/a/53479618/1452758