问题描述
我有一个挂在UISwitch
上的rx
。无论何时切换,都会显示alertView
。如果选择“确定”,则将发生一些事情,但是如果按“取消”,则将不会发生任何事情,并且UISwitch
将保留在同一位置,即不会切换。
mySwitch.rx.controlEvent(.valueChanged).subscribe(onNext: { [weak self] _ in
guard let self = self else { return }
CustomAlertViewController.standardTwoButtonMessageAlert(title: self.mySwitch.isOn ? "Do you want to turn this on?" : "Do you want to turn this off?",msg: "hello",action: {
print("Doing stuff")
},cancelAction: {
//SHOULD NOT TOGGLE
})?.present(animated: true,onView: UIApplication.topViewController())
}).disposed(by: disposeBag)
还有一个问题,当我到达UISwitch
时已经切换了cancelAction
,这意味着需要再次将其切换回去。如何切换回去?有没有办法完全阻止它切换,以便我可以在闭包内部手动进行管理?
解决方法
此问题描述了两个原因(用户切换开关并点击取消按钮)和三个效果(显示警报,关闭开关并“正在做事”。)让我们为每种效果解决。
当拨动开关打开时,我们会显示警报...由于我们需要警报按钮发出的值,因此这种影响也可能是其他影响的原因。这意味着我们使用flatMap而不是订阅:
let alertResult = settingSwitch.rx.isOn
.filter { $0 }
.map { _ in }
.flatMapFirst { [unowned self] in
self.present(alert(title: "Hello",message: "Are you sure?"),animated: true)
}
.share(replay: 1)
如果用户点击警报上的取消按钮,那么我们需要关闭开关。
alertResult
.filter { $0 == .cancel }
.map { _ in false }
.bind(to: settingSwitch.rx.isOn)
.disposed(by: disposeBag)
如果用户点击警报上的“确定”按钮,那么我们需要做些事情。
alertResult
.filter { $0 == .ok }
.map { _ in }
.subscribe(onNext: {
doStuff()
})
.disposed(by: disposeBag)
所有这些都假定您不介意在警报启动时将开关置于打开位置。如果您想阻止这种情况的发生,则需要在开关上放一个按钮,并使开关只是一种效果,而不是原因。