【问题标题】:if else condition in RXSwiftRXSwift 中的 if else 条件
【发布时间】:2021-03-08 03:38:25
【问题描述】:

有一个使用 RXSwift 进行验证的文本字段。我想禁用基于开关操作的验证。

 // Start Time
 startTimeValid = startTimeTextfield.rx.text.orEmpty.map{
            $0.count > 0
  }

 // End time
 endTimeValid = endTimeTextfield.rx.text.orEmpty.map{
            $0.count > 0
 }

 everythingValid = Observable.combineLatest(startTimeValid,endTimeValid){ $0 && $1 }
        

 endTimeValid.bind(to: endTimeErrorLabel.rx.isHidden).disposed(by: bag)
 startTimeValid.bind(to: startTimeErrorLabel.rx.isHidden).disposed(by: bag)
 everythingValid.bind(to: createButton.rx.isEnabled).disposed(by: bag)

        
 createButton.rx.tap.subscribe(onNext:{

            print("success")

        }).disposed(by: bag)

所以在上面的代码中,结束时间和开始时间文本字段都正在验证中。基于布尔值,我需要禁用 EndTime 文本字段的验证。

我试过的代码:

 @objc func endDateRequired(_ aSwitch : UISwitch){

        
        if aSwitch.isOn{

            everythingValid = Observable.combineLatest(eventTitleValid, startDateValid, endDateValid){ $0 && $1 && $2
            }
            everythingValid.bind(to: createButton.rx.isEnabled).disposed(by: bag)
       
        }else{
            
            everythingValid = Observable.combineLatest(eventTitleValid, startDateValid, endDateValid, startTimeValid,endTimeValid){ $0 && $1 && $2 && $3 && $4
            }
            everythingValid.bind(to: createButton.rx.isEnabled).disposed(by: bag)

        }
        
    }

我正在尝试将其简化为反应式。

【问题讨论】:

    标签: ios uitextfield rx-swift


    【解决方案1】:

    @matt 有正确的答案,但在 RxSwift 中解决方案更简单,因为全局 combineLatest 运算符最多可以使用 8 个参数...

    Observable.combineLatest(
        startTimeTextField.rx.text.orEmpty,
        endTimeTextField.rx.text.orEmpty,
        endDateRequired.rx.isOn
    )
    { startTime, endTime, endDateRequired in
        !startTime.isEmpty && (!endTime.isEmpty || !endDateRequired)
    }
    .bind(to: createButton.rx.isEnabled)
    .disposed(by: disposeBag)
    

    【讨论】:

    • 酷,而且它给了我一个改进我的想法。 :)。
    【解决方案2】:

    我不知道 RxSwift,但我可以看到问题在于像 if aSwitch.isOn 这样的行不是响应式的。您还需要观察开关,并考虑所有的值。

    这是一个 Combine 示例,毫无疑问,它以某种简单的方式转化为 RxSwift。我们有两个文本字段、一个开关和一个按钮。仅当两个文本字段都有内容时才启用该按钮,除非关闭开关,在这种情况下,该按钮只是被启用(无验证):

    class ViewController: UIViewController {
        @IBOutlet weak var tf1: UITextField!
        @IBOutlet weak var tf2: UITextField!
        @IBOutlet weak var sw: UISwitch!
        @IBOutlet weak var button: UIButton!
        var storage = Set<AnyCancellable>()
        override func viewDidLoad() {
            super.viewDidLoad()
            let tfpub1 = tf1.publisher(for:.editingChanged)
                .map {$0.text ?? ""}
                .prepend("")
            let tfpub2 = tf2.publisher(for:.editingChanged)
                .map {$0.text ?? ""}
                .prepend("")
            let swpub = sw.publisher()
                .map {$0.isOn}
                .prepend(true)
            tfpub1.combineLatest(tfpub2, swpub)
                .map { !$2 || ( $0.count > 0 && $1.count > 0 ) }
                .assign(to: \.isEnabled, on: self.button)
                .store(in: &storage)
        }
    }
    

    UIControlpublisher方法见我的https://www.apeth.com/UnderstandingCombine/publishers/publisherscustom.html

    【讨论】:

    • .assign(to: \.isEnabled, on: button) 有用吗?如果是这样,我觉得会更好。
    • 是的,我认为它可能会避免保留周期。我会检查的。
    • 是的,确实如此:我讨厌assign,我认为这是一个错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    相关资源
    最近更新 更多