Ich habe drei Knöpfe und ich möchte, dass sie nur eine zu einem Zeitpunkt ausgewählt werden:RxSwift und isSelected Eigenschaft auf UIButton
und:
etc ...
Mein Ansatz ist dies:
class MyController: UIViewController {
@IBOutlet var buttonOne: UIButton!
@IBOutlet var buttonTwo: UIButton!
@IBOutlet var buttonThree: UIButton!
var buttonOneIsSelected = Variable(true)
var buttonTwoIsSelected = Variable(false)
var buttonThreeIsSelected = Variable(false)
override func viewDidLoad() {
super.viewDidLoad()
buttonOne.isSelected = true
buttonOneIsSelected.asDriver()
.drive(buttonOne.rx.isSelected)
.disposed(by: disposeBag)
buttonTwoIsSelected.asDriver()
.drive(buttonTwo.rx.isSelected)
.disposed(by: disposeBag)
buttonThreeIsSelected.asDriver()
.drive(buttonThree.rx.isSelected)
.disposed(by: disposeBag)
buttonOne.rx.tap.asObservable().map { (_) -> Bool in
return !self.buttonOne.isSelected
}
.do(onNext: { (isSelected) in
self.buttonTwoIsSelected.value = !isSelected
self.buttonThreeIsSelected.value = !isSelected
})
.bindTo(buttonOne.rx.isSelected)
.disposed(by: disposeBag)
buttonTwo.rx.tap.asObservable().map { (_) -> Bool in
return !self.buttonTwo.isSelected
}
.do(onNext: { (isSelected) in
self.buttonOneIsSelected.value = !isSelected
self.buttonThreeIsSelected.value = !isSelected
})
.bindTo(buttonTwo.rx.isSelected)
.disposed(by: disposeBag)
buttonThree.rx.tap.asObservable().map { (_) -> Bool in
return !self.buttonThree.isSelected
}
.do(onNext: { (isSelected) in
self.buttonOneIsSelected.value = !isSelected
self.buttonTwoIsSelected.value = !isSelected
})
.bindTo(buttonThree.rx.isSelected)
.disposed(by: disposeBag)
}
Gibt es einen besseren Ansatz? Es funktioniert, aber gibt es einen besseren "reaktiven" Weg, es mit RxSwift zu machen?
Vielen Dank für die Antwort. Ich bin ziemlich neu in der reaktiven Programmierung. Der Operator zu reduzieren ist ein bisschen schwierig für mich zu erfassen. Verfügen Sie über erläuternde Ressourcen für RxSwift im Allgemeinen (oder speziell für den Reduce Operator), um mein Wissen zu erweitern? – TheoK
'reduce' ist eigentlich eine regelmäßige schnelle Sequenzmethode. Es braucht einen Startwert und einen Akkumulator. Das einfachste Beispiel ist "[1, 2, 3] .reduce (0) {$ 0 + $ 1}". Dies berechnet '((0 + 1) + 2) + 3 = 6 '. In unserem Fall kann man sich das Ergebnis als "Disposable.create (Disposable.create (Disposable.create (emptyDisposable, button1Disposable), button2Disposable), button3Disposable)' – tomahh
Great @tomahh vorstellen. Wenn ich richtig verstanden habe, gibt Ihnen die Methode reduce die Möglichkeit, eine Funktion auf jedes Element des Arrays anzuwenden und dann ein einzelnes Abonnement zu erstellen, statt eines für jedes Element zu erstellen, richtig? Und der Grund, warum Sie ein Disposable zurückgeben, liegt daran, dass die bindTo-Methode ein Disposable erstellt? Die Umsetzung im Inneren reduziert mich ein wenig. (Sorry für die Fragen, aber ich möchte die Begründung hinter der Implementierung verstehen :)) – TheoK