接上期:【RxSwift 實踐系列 2/3】thinking in Rx- Create和Drive的功能,咱們要實如今uitableview中cell上按鈕功能。一樣,咱們在cell上直接訂閱這個按鈕,當接受到點擊請求的時候,UserDefaults上去git
以下:github
searchFiled.rx.text
.filter{
($0?.lengthOfBytes(using: .utf8))! > 0 //長度大於1
}
.throttle(0.5, scheduler: MainScheduler.instance) //延遲0.5秒再執行
.flatMap{
ListViewModel().searchFromApi(repositoryName:String(describing: $0!))
}
.asDriver(onErrorJustReturn: [])
.drive(resultTableView.rx.items(cellIdentifier: "SearchTableViewCell", cellType: SearchTableViewCell.self)) {
(tableView, element, cell) in
cell.nameLabel.text = element.name
cell.codeLabel.text = element.code
cell.addBtn.rx.tap.subscribe(
onNext: {
var stocks = UserDefaults.standard.array(forKey: "stockSelected") as! [String]
stocks.append(element.code)
UserDefaults.standard.set(stocks, forKey: "stockSelected")
cell.addBtn.setTitle("已關注", for: .normal)
}
).disposed(by: rx.disposeBag)
}
.disposed(by: rx.disposeBag)
複製代碼
可是實際操做上發現問題了,當搜索框輸入在不斷變化的時候,cell也是在不斷的刷新的,cell重用的時候,按鈕就會被屢次訂閱,形成嚴重的bug。這裏就要用到一個方法:prepareForReuseswift
private(set) var disposeBag = DisposeBag()
//SearchTableViewCell中實現
override func prepareForReuse() {
super.prepareForReuse()
disposeBag = DisposeBag()
}
複製代碼
在每次重用cell的時候,咱們會釋放以前的disposeBag,而後會爲cell建立一個新的disposeBag對象,避免屢次訂閱.bash
cell.addBtn.rx.tap.subscribe(
onNext: {
var stocks = UserDefaults.standard.array(forKey: "stockSelected") as! [String]
stocks.append(element.code)
UserDefaults.standard.set(stocks, forKey: "stockSelected")
cell.addBtn.setTitle("已關注", for: .normal)
}
).disposed(by: cell.disposeBag)//注意,這裏是cell的disposeBag
複製代碼
這樣咱們就實現了cell上按鈕的實現。網絡
最後就是首頁列表展現了,首頁的展現和搜索列表同樣,這裏就不囉嗦了,這裏有個難點是,股票的價格在不刷新tableview的狀況下更新,在日常的實現裏咱們只能使用刷新單個cell來實現了,來看看rx的實現方式:app
ListViewModel().getFromApi(repositoryName: "").subscribe(
onNext:{ rs in Observable<[ListModel]>
.just(rs)
.bind(to: self.resultTableView.rx.items(cellIdentifier: "ListTableViewCell", cellType: ListTableViewCell.self)) {(_, model:ListModel, cell:ListTableViewCell) in
//定時任務每兩秒執行一次
Observable<Int>.interval(2, scheduler: MainScheduler.instance).subscribe { (event) in
ListViewModel().getOne(repositoryName: model.symbol)
.subscribe(
onNext:{ rs in Observable<ListModel>
.just(rs)
.subscribe{
cell.currentLabel.text = String(describing: rs.current)
cell.nameLabel.text = rs.name
cell.codeLabel.text = rs.code
}.disposed(by: self.rx.disposeBag)
}
).disposed(by: self.rx.disposeBag)
}.disposed(by: self.rx.disposeBag)
}.disposed(by: self.rx.disposeBag)
}
).disposed(by: rx.disposeBag)
複製代碼
在綁定的cell裏面,對整個cell作一個定時任務interval,每秒獲取一次網絡數據,訂閱這個數據來更新cell的元素,從而實現了cell無刷新的更新。能夠說代碼上只增長了3行就實現了這個功能!ide
這個用rxSwift實現的添加股票代碼實時刷新價格的應用到這裏就完成了,能夠在這裏找到實例代碼。post
代碼裏面還有不少缺陷和須要優化的地方: 好比不少的if else能夠用rxSwift作的更簡潔、許多錯誤異常等並無處理,網絡受權的提示、添加股票代碼後首頁並無及時更新。你們能夠嘗試着用rxSwift繼續優化代碼。優化
三期連接:ui