RxSwiftiOS 进阶开发Swift开发进阶

RxSwift-MVVM双向绑定

2019-08-14  本文已影响34人  Cooci_和谐学习_不急不躁

RxSwift 篇章已经接近尾声,回首这个历程很累但很充实:白天备课,晚上VIP上课!忙里偷闲写下了这个篇章。可以说:痛并快乐着

当我列出下面的列表的时候,突然发现好幸福,每一个篇章,都是自己坚持的成功,都是自己努力的收获,感谢自己每个凌晨的灵感,感谢陪我一起前行的我的周边人

就问此时此刻还有谁?45度仰望天空,该死!我这无处安放的魅力!

一、首先面向开发我们看看RxSwift在TableView的应用

/// tableView -- RX
func setupTableViewRX() {
    let dataOB = BehaviorSubject.init(value: self.viewModel.dataArray)
    // 骚起来
//        dataOB.bind(to: self.tableView.rx.items){(tabView,row,model) ->LGTableViewCell in
//            let cell = tabView.dequeueReusableCell(withIdentifier: resuseID) as! LGTableViewCell
//            cell.setUIData(model as! LGModel)
//            return cell
//        }.disposed(by: disposeBag)
    
    dataOB.asObserver().bind(to: self.tableView.rx.items(cellIdentifier: resuseID, cellType: LGTableViewCell.self)){
        (row,model,cell) in
        cell.setUIData(model as! LGModel)
    }.disposed(by: self.disposeBag)
    
    // tableView点击事件
    tableView.rx.itemSelected.subscribe(onNext: { [weak self](indexPath) in
        print("点击\(indexPath)行")
        self?.navigationController?.pushViewController(LGSectionViewController(), animated: true)
        self?.tableView.deselectRow(at: indexPath, animated: true)
    }).disposed(by: self.disposeBag)
    
    // tableView复选点击事件
    tableView.rx.itemDeselected.subscribe(onNext: { (indexPath) in
        print("再次点击\(indexPath)行")
    }).disposed(by: self.disposeBag)
    
    // tableView移动事件
    tableView.rx.itemMoved.subscribe(onNext: { [weak self] (sourceIndex,destinationIndex) in
        print("从\(sourceIndex)移动到\(destinationIndex)")
        self?.viewModel.dataArray.swapAt(sourceIndex.row, destinationIndex.row)
        self?.loadUI(obSubject: dataOB)
    }).disposed(by: self.disposeBag)
    
    // tableView删除事件
    tableView.rx.itemDeleted.subscribe(onNext: { [weak self](indexPath) in
        print("点击删除\(indexPath)行")
        self?.viewModel.dataArray.remove(at: indexPath.row)
        self?.loadUI(obSubject: dataOB)
    }).disposed(by: self.disposeBag)
    
    // tableView新增事件
    tableView.rx.itemInserted.subscribe(onNext: { [weak self](indexPath) in
        print("添加数据在\(indexPath)行")
        guard let model = self?.viewModel.dataArray.last else{
            print("数据有问题,无法新增")
            return
        }
        self?.viewModel.dataArray.insert(model, at: indexPath.row)
        self?.loadUI(obSubject: dataOB)
    }).disposed(by: self.disposeBag)    
}

二、分组的TableView

/// Rx 处理分组
func setupTableViewRX() {
    let tableViewDataSource = RxTableViewSectionedReloadDataSource<SectionModel<String,LGSectionModel>>(configureCell: { [weak self](dataSource, tab, indexPath, model) -> LGTableViewCell in
        let cell = tab.dequeueReusableCell(withIdentifier: self?.resuseID ?? "resuseID_LGSectionViewController", for: indexPath) as! LGTableViewCell
        cell.setUISectionData(model)
        cell.selectionStyle = .none
        return cell
    },titleForHeaderInSection: { dataSource,index -> String in
        // print("数据:\(dataSource.sectionModels[index].identity)")
        return dataSource.sectionModels[index].model
    })

    /// 我们上次就是通过bind函数,这里我们变化一下
    self.data.githubData.asDriver(onErrorJustReturn: [])
        .drive(self.tableView.rx.items(dataSource: tableViewDataSource))
        .disposed(by: self.disposeBag)
    
    /// 跳转到网络相关Demo
    self.tableView.rx.itemSelected.subscribe(onNext: { [weak self](indexPath) in
        self?.navigationController?.pushViewController(LGNetworkViewController(), animated: true)
    }).disposed(by: self.disposeBag)
}

MVVM双向绑定

override func viewDidLoad() {
    super.viewDidLoad()
    self.setupUI()
    // 现在来一个需求:我们的输入框搜索 - 请求网络 - 下面tableView联动
    // UI <-> model
    self.searchBar.rx.text.orEmpty
        .bind(to: self.viewModel.searchTextOB)
        .disposed(by: disposeBag)
    
   // 数据层绑定UI
    self.viewModel.searchData.drive(self.tableView.rx.items){ (tableView, indexPath, model) -> LGTableViewCell in
        let cell = tableView.dequeueReusableCell(withIdentifier: self.resuseID) as! LGTableViewCell
        cell.nameLabel.text  = model.name
        cell.classLabel.text = model.url
        return cell
    }
    .disposed(by: disposeBag)
    
    // tittle绑定
    self.viewModel.searchData.map { (array) -> String in
        return "搜索到了 \(array.count) 条数据"
    }
    .drive(self.navigationItem.rx.title)
    .disposed(by: disposeBag)
    
    // 滑动减速绑定
    self.tableView.rx.didEndDecelerating
        .subscribe { [weak self] in
            self?.searchBar.endEditing(true)
    }.disposed(by: disposeBag)
}
lazy var searchData: Driver<[LGReposityModel]> = {
    return self.searchTextOB.asObserver()
        .throttle(RxTimeInterval.milliseconds(300), scheduler: MainScheduler.instance)
        .distinctUntilChanged()
        .flatMapFirst(LGComprehensiveViewModel.resposeData)
        .asDriver(onErrorJustReturn: [])
}()
static func resposeData(_ githunId: String) -> Observable<[LGReposityModel]> {
    guard !githunId.isEmpty,let url = URL(string: "https://api.github.com/users/\(githunId)/repos") else {
        return Observable.just([])
    }
    
   return URLSession.shared.rx.json(url: url)
            .retry()
            .observeOn(ConcurrentDispatchQueueScheduler(qos: .background))
            .map(LGComprehensiveViewModel.parseData)
}
static func parseData(_ json: Any) -> [LGReposityModel] {
    guard let items = json as? [[String: Any]] else {return []}
    guard let result = [LGReposityModel].deserialize(from: items) else { return [] }
    return result as! [LGReposityModel]
}

完美实现联动,MVVM双向绑定加入RxSwift的身影也就更出色

所有的努力都会在某一个时刻兑现,我们很多小伙伴都会感叹怎么还不来!你要知道:毋庸置疑,好的事情总会到来,当他来晚的时候也不失为一种惊喜

就问此时此刻还有谁?45度仰望天空,该死!我这无处安放的魅力!

上一篇下一篇

猜你喜欢

热点阅读