UIButton 上的 RxSwift 和 isSelected 属性
RxSwift and isSelected property on UIButton
我有三个按钮,我希望一次只选择一个:
和:
等...
我的做法是这样的:
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)
}
有没有更好的方法?它有效,但是有没有更好的 'reactive' 方法通过使用 RxSwift 来做到这一点?
Subject
和扩展 Variable
大多数时候仅在从命令式世界过渡到反应式世界时有用。在这里,你可以没有它们。
.do(onNext:)
也是一种执行副作用的方法,这是您在反应式代码中通常不希望看到的。
// force unwrap to avoid having to deal with optionals later on
let buttons = [button1, button2, button3].map { [=10=]! }
// create an observable that will emit the last tapped button (which is
// the one we want selected)
let selectedButton = Observable.from(
buttons.map { button in button.rx.tap.map { button } }
).merge()
// for each button, create a subscription that will set its `isSelected`
// state on or off if it is the one emmited by selectedButton
buttons.reduce(Disposables.create()) { disposable, button in
let subscription = selectedButton.map { [=10=] == button }
.bindTo(button.rx.isSelected)
// combine two disposable together so that we can simply call
// .dispose() and the result of reduce if we want to stop all
// subscriptions
return Disposables.create(disposable, subscription)
}
.addDisposableTo(disposeBag)
我有三个按钮,我希望一次只选择一个:
和:
等...
我的做法是这样的:
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)
}
有没有更好的方法?它有效,但是有没有更好的 'reactive' 方法通过使用 RxSwift 来做到这一点?
Subject
和扩展 Variable
大多数时候仅在从命令式世界过渡到反应式世界时有用。在这里,你可以没有它们。
.do(onNext:)
也是一种执行副作用的方法,这是您在反应式代码中通常不希望看到的。
// force unwrap to avoid having to deal with optionals later on
let buttons = [button1, button2, button3].map { [=10=]! }
// create an observable that will emit the last tapped button (which is
// the one we want selected)
let selectedButton = Observable.from(
buttons.map { button in button.rx.tap.map { button } }
).merge()
// for each button, create a subscription that will set its `isSelected`
// state on or off if it is the one emmited by selectedButton
buttons.reduce(Disposables.create()) { disposable, button in
let subscription = selectedButton.map { [=10=] == button }
.bindTo(button.rx.isSelected)
// combine two disposable together so that we can simply call
// .dispose() and the result of reduce if we want to stop all
// subscriptions
return Disposables.create(disposable, subscription)
}
.addDisposableTo(disposeBag)