There is a UISwitch
and a ControlProperty<Bool>
which are bound each other. However I cannot use standard two-way binding operator <->
because of the following requirements:
If user turns UISwitch
ON, I need to check some condition and, if not met, show an alert and revert UISwitch
back to OFF state. ControlProperty
must remain intact.
If condition met, ControlProperty
becomes true
.
If user turns UISwitch
OFF, ControlProperty
becomes false
.
If ControlProperty
has been (externally) changed, UISwitch
must reflect its state unconditionally (as normal binding works). The condition must not be checked.
I tried the following (maybe naive) approach:
property.bind(to: cell.switch.rx.isOn).disposed(by: cell.disposeBag)
cell.switch.rx.isOn.bind { [unowned self] isOn in
if !isOn || viewModel.allowTurnEmailNotificationOn {
property.onNext(isOn)
} else {
let alert = MyAlertViewController()
present(alert, animated: true) { [weak cell] in
// revert switch back to OFF state
cell?.switch.isOn = false
}
}
}.disposed(by: cell.disposeBag)
Generally, it works, but there is a bug: when ControlProperty
changes to TRUE due to some external event, it sets UISwitch
ON, which in turn launches checking if !isOn || viewModel.allowTurnEmailNotificationOn
. As a result, the alert appears.
I only want to perform this check if user manually turns UISwitch
ON.