if else 条件在 RXSwift
if else condition in RXSwift
有一个使用 RXSwift 进行验证的文本字段。我想禁用基于开关操作的验证。
// Start Time
startTimeValid = startTimeTextfield.rx.text.orEmpty.map{
[=10=].count > 0
}
// End time
endTimeValid = endTimeTextfield.rx.text.orEmpty.map{
[=10=].count > 0
}
everythingValid = Observable.combineLatest(startTimeValid,endTimeValid){ [=10=] && }
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){ [=11=] && &&
}
everythingValid.bind(to: createButton.rx.isEnabled).disposed(by: bag)
}else{
everythingValid = Observable.combineLatest(eventTitleValid, startDateValid, endDateValid, startTimeValid,endTimeValid){ [=11=] && && && &&
}
everythingValid.bind(to: createButton.rx.isEnabled).disposed(by: bag)
}
}
我正在努力以反应式的方式简化它。
我不知道 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 {[=10=].text ?? ""}
.prepend("")
let tfpub2 = tf2.publisher(for:.editingChanged)
.map {[=10=].text ?? ""}
.prepend("")
let swpub = sw.publisher()
.map {[=10=].isOn}
.prepend(true)
tfpub1.combineLatest(tfpub2, swpub)
.map { ! || ( [=10=].count > 0 && .count > 0 ) }
.assign(to: \.isEnabled, on: self.button)
.store(in: &storage)
}
}
关于 UIControl publisher
方法,请参阅我的 https://www.apeth.com/UnderstandingCombine/publishers/publisherscustom.html
@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)
有一个使用 RXSwift 进行验证的文本字段。我想禁用基于开关操作的验证。
// Start Time
startTimeValid = startTimeTextfield.rx.text.orEmpty.map{
[=10=].count > 0
}
// End time
endTimeValid = endTimeTextfield.rx.text.orEmpty.map{
[=10=].count > 0
}
everythingValid = Observable.combineLatest(startTimeValid,endTimeValid){ [=10=] && }
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){ [=11=] && &&
}
everythingValid.bind(to: createButton.rx.isEnabled).disposed(by: bag)
}else{
everythingValid = Observable.combineLatest(eventTitleValid, startDateValid, endDateValid, startTimeValid,endTimeValid){ [=11=] && && && &&
}
everythingValid.bind(to: createButton.rx.isEnabled).disposed(by: bag)
}
}
我正在努力以反应式的方式简化它。
我不知道 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 {[=10=].text ?? ""}
.prepend("")
let tfpub2 = tf2.publisher(for:.editingChanged)
.map {[=10=].text ?? ""}
.prepend("")
let swpub = sw.publisher()
.map {[=10=].isOn}
.prepend(true)
tfpub1.combineLatest(tfpub2, swpub)
.map { ! || ( [=10=].count > 0 && .count > 0 ) }
.assign(to: \.isEnabled, on: self.button)
.store(in: &storage)
}
}
关于 UIControl publisher
方法,请参阅我的 https://www.apeth.com/UnderstandingCombine/publishers/publisherscustom.html
@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)