在之前我們的舉例、使用的時候,我們所有的綁定都是單向的,但是,有時候我們還是需要雙向綁定的。就比如說,把某個控件的某個屬性值與
ViewModel中的某個Subject屬性進行雙向綁定:
- 這樣當(dāng)
ViewModel里的值發(fā)生改變時,可以同步反映到控件上。- 而如果對控件值做修改,
ViewModel那邊值同時也會發(fā)生變化。
比較簡單的雙向綁定
- 咱們的頁面上有一個文本輸入框,用于填寫用戶姓名,把它與
ViewModel中的username屬性做雙向綁定- 文本框下方有一個文本標(biāo)簽
label,會根據(jù)用戶名顯示對應(yīng)的用戶信息,只有"admin"顯示管理員,其他都顯示訪客
(1)首先定義一個ViewModel:
struct UserViewModel {
//用戶名
let username = Variable("guest")
//用戶信息
lazy var userinfo = {
return self.username.asObservable()
.map{ $0 == "admin ? "管理員" : "普通訪客" }
.share(replay: 1)
}()
}
(2)進行雙向綁定:
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var label: UILabel!
var userVM = UserViewModel()
let disposeBag = DisposeBag()
override func viewDidLoad() {
//將用戶名與textField做雙向綁定
userVM.username.asObservable().bind(to: textField.rx.text).disposed(by: disposeBag)
textField.rx.text.orEmpty.bind(to: userVM.username).disposed(by: disposeBag)
//將用戶信息綁定到label上
userVM.userinfo.bind(to: label.rx.text).disposed(by: disposeBag)
}
}
備注:目前:'Variable' API已被標(biāo)記為廢棄,之后的API請使用BehaviorRelay代替。
使用自定義雙向綁定操作符(operator)
- 如果經(jīng)常進行雙向綁定的話,最好還是自定義一個
operator方便使用。- 好在
RxSwift項目文件夾中已經(jīng)有個現(xiàn)成的Operators.swift,我們將它復(fù)制到我們項目中即可使用。當(dāng)然如我們想自己寫一些其它的雙向綁定operator也可以參考它。
雙向綁定操作符是:
<->。我們修改上面樣例,可以發(fā)現(xiàn)代碼精簡了許多。
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var label: UILabel!
var userVM = UserViewModel()
let disposeBag = DisposeBag()
override func viewDidLoad() {
//將用戶名與textField做雙向綁定
_ = self.textField.rx.textInput <-> self.userVM.username
//將用戶信息綁定到label上
userVM.userinfo.bind(to: label.rx.text).disposed(by: disposeBag)
}
}