在之前我们的举例、使用的时候,我们所有的绑定都是单向的,但是,有时候我们还是需要双向绑定的。就比如说,把某个控件的某个属性值与
ViewModel
中的某个Subject
属性进行双向绑定:
- 这样当
ViewModel
里的值发生改变时,可以同步反映到控件上。- 而如果对控件值做修改,
ViewModel
那边值同时也会发生变化。
比较简单的双向绑定
- 咱们的页面上有一个文本输入框,用于填写用户姓名,把它与
ViewModel
中的username
属性做双向绑定- 文本框下方有一个文本标签
label
,会根据用户名显示对应的用户信息,只有"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已被标记为废弃,之后的API请使用BehaviorRelay
代替。
使用自定义双向绑定操作符(operator)
- 如果经常进行双向绑定的话,最好还是自定义一个
operator
方便使用。- 好在
RxSwift
项目文件夹中已经有个现成的Operators.swift
,我们将它复制到我们项目中即可使用。当然如我们想自己写一些其它的双向绑定operator
也可以参考它。
双向绑定操作符是:
<->
。我们修改上面样例,可以发现代码精简了许多。
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)
}
}