接下來,我們繼續(xù)實現(xiàn)上個視頻中未完成的例子。首先來處理UISwitch和UISlider聯(lián)動。
對于UISwitch來說:
- 當(dāng)
UISwitch為OFF時,表示用戶不了解Swift,因此,下面的UISlider應(yīng)該為0; - 當(dāng)
UISwitch為ON時,可以默認(rèn)把UISlider設(shè)置在1/4的位置,表示大致了解;
對于UISlider來說:
- 當(dāng)
UISlider不為0時,應(yīng)該自動把UISwitch設(shè)置為ON; - 當(dāng)
UISlider為0時,應(yīng)該自動把UISwitch設(shè)置為OFF;
怎么做呢?
RxSwift對UISwitch和UISlider也進(jìn)行了擴(kuò)展,分別給它們添加了一個叫做rx_value的屬性。在UISwitch里,它的類型是ControlProperty<Bool>;在UISlider里,它的類型是ControlProperty<Float>。和Variable類似,ControlProperty也可以既是Observer,又是Observable。
先來處理UISwitch:
self.knowSwift.rx_value.map {
$0 ? 0.25 : 0
}
.bindTo(self.swiftLevel.rx_value)
.addDisposableTo(self.bag)
我們先把self.knowSwift.rx_value當(dāng)成observable,ON的時候,事件值為true,OFF的時候,事件值為false。我們先把它分別map成0.25和0,然后使用bindTo,用self.swiftLevel.rx_value來訂閱這個map后的事件。
這樣,我們就建立了UISwitch到UISlider之間的關(guān)聯(lián),當(dāng)ON時,UISlider在1/4的位置,OFF時,UISlider的值為0。
然后,我們用類似的方式建立UISlider到UISwitch之間的關(guān)聯(lián):
self.swiftLevel.rx_value.map {
$0 != 0 ? true : false
}
.bindTo(self.knowSwift.rx_value)
.addDisposableTo(self.bag)
這樣,當(dāng)UISlider為0時,就會把UISwitch設(shè)置為OFF,否則為ON。
至此,UISwitch和UISlider的rx_value就實現(xiàn)了雙向綁定。按Command + R就可以看到期望的結(jié)果了。

訂閱UIStepper
最后,我們來實現(xiàn)UIStepper。我們希望實現(xiàn)點(diǎn)擊加號的時候,讓桃心變大,減號時,讓桃心變小。類似的,RxSwift給UIStepper也添加了一個擴(kuò)展rx_value,它的類型是ControlProperty<Double>。于是,訂閱它的套路我們應(yīng)該很熟悉了:
self.passionToLearn.rx_value.subscribeNext({
(stepperValue: Double) in
self.heartHeight.constant = CGFloat(stepperValue - 10)
}).addDisposableTo(self.bag)
為了修正桃心圖片伸縮的幅度,我們在調(diào)整桃心圖片的高度約束時,把UIStepper的值減去了10。這時Command + R編譯執(zhí)行,可以看到,大部分功能正確,卻有一個小缺陷。

當(dāng)UI被加載后,由于UIStepper默認(rèn)的值是20,會向observer發(fā)送一次事件,因此,桃心的默認(rèn)高度被減了10。為了解決這個問題,我們需要告訴observer忽略第一次事件。為此,在訂閱前,我們使用skip(1)就可以了:
self.passionToLearn.rx_value.skip(1).subscribeNext({
(stepperValue: Double) in
self.heartHeight.constant = CGFloat(stepperValue - 10)
}).addDisposableTo(self.bag)
這樣,Command + R重編編譯執(zhí)行,就可以看到桃心默認(rèn)大小恢復(fù)正常了。
