1. share(replay: 1)
同一个 Observable 绑定多次, Observable 会被创建多次, 使用 share(replay: 1) 共享数据源
例: 将 DatePicker 创建为一个 Observable, 绑定两次, 如果不使用 share(replay: 1), DatePicker
会被创建两次, 弹出两次.
/// 创建时间选择器 Observable
func createDatePickerObservable() -> Observable<String> {
let tmpObservable: Observable<String> = Observable.create({ (observer) -> Disposable in
let datePicker = WSDatePickerView(dateStyle: DateStyleShowYearMonthDay) { (date) in
guard let date = date else {
observer.onError(YPProjectExpError.illegalData("Date 为 nil"))
return
}
let timeStr = YPFunctionTool.dateToStr(date: date)
observer.onNext(timeStr)
observer.onCompleted()
}
datePicker?.doneButtonColor = ColorBlue
datePicker?.show()
return Disposables.create()
})
return tmpObservable
}
/// 绑定
let startPicker = self.createDatePickerObservable().share(replay: 1)
startPicker.asDriver(onErrorJustReturn: "").drive { timeStr in
} onCompleted: {
} onDisposed: {
}.disposed(by: rx.disposeBag)
startPicker.asDriver(onErrorJustReturn: "").drive { timeStr in
} onCompleted: {
} onDisposed: {
}.disposed(by: rx.disposeBag)
2. 先创建 disposeBag, 再绑定; DisposeBag 重新赋值后, 需重新绑定
例1: 下边代码中 disposeBag 重新被赋值后, 按钮不会响应点击事件, 需要重新绑定
var disposeBag = DisposeBag()
lazy var okButton: UIButton = {
let button = UIButton()
button.setTitleColor(.white, for: .normal)
button.backgroundColor = .blue
button.setTitle("确定", for: .normal)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(okButton)
okButton.snp.makeConstraints { make in
make.center.equalToSuperview()
make.width.equalTo(200)
}
okButton.rx.tap.bind { [weak self] in
print("******************")
}.disposed(by: self.disposeBag)
self.disposeBag = DisposeBag()
}
例2: 在 tableView, collectionView 中, cell 重用时, disposeBag 会在 prepare 方法中被重新赋值,
deleteBtn, reUploadBtn 的点击事件不会响应
class JLImagesCCell: UICollectionViewCell {
var disposeBag: DisposeBag = DisposeBag()
private lazy var deleteBtn: UIButton = {
let button = UIButton()
button.setImage(UIImage(named: "delete_image_icon"), for: .normal)
button.rx.tap.debug().bind(to: self.deleteImg).disposed(by: rx.disposeBag)
return button
}()
/// 重新上传按钮
private lazy var reUploadBtn: UIButton = {
let button = UIButton()
button.setTitle("上传失败\n请重新选择", for: .normal)
button.rx.tap.debug().bind(to: self.rechooseImg).disposed(by: rx.disposeBag)
return button
}()
override func prepareForReuse() {
super.prepareForReuse()
self.disposeBag = DisposeBag()
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
3. bind, subscribe 简写, 删掉 onError, onCompleted, onDisposed, 所有逻辑都走 onNext
对于 onError, onCompleted, onDisposed 有不同处理的, 不能删掉
Observable().subscribe {
print("onNext*************")
} onError: { _ in
print("onError*************")
} onCompleted: {
print("onCompleted*************")
} onDisposed: {
print("onDisposed*************")
}.disposed(by: disposeBag)
// 简写
Observable(()).subscribe {
}.disposed(by: disposeBag)
4. textView 可以使用map 过滤输入字符, 限制输入字数, 但是只能直接使用 textView.rx.text 作为 Observer, 不能使用 textView.text = str
contentTV.rx.text.orEmpty.asObservable().map({ oldStr -> String in
return oldStr.filter({ $0 != "\n" }).filterPrefix(max: 12)
}).bind(to: contentTV.rx.text).disposed(by: disposeBag)
错误写法
输入汉字时会实时返回, 不能连续输入
contentTV.rx.text.orEmpty.asObservable().map({ oldStr -> String in
return oldStr.filter({ $0 != "\n" }).filterPrefix(max: 12)
}).bind { [weak self](str) in
self?.contentTV.text = str
}.disposed(by: disposeBag)