如何停止使用rx swift切换UISwitch?

问题描述

我有一个挂在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)

所有这些都假定您不介意在警报启动时将开关置于打开位置。如果您想阻止这种情况的发生,则需要在开关上放一个按钮,并使开关只是一种效果,而不是原因。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...