|
//
// UITableViewExt+rx.swift
// PaiAi
//
// Created by LISA on 2017/5/18.
// Copyright © 2017年 yb. All rights reserved.
//
import UIKit
import RxSwift
import RxCocoa
class FFTableViewReactiveArrayDataSource<Element>
: NSObject, UITableViewDataSource, SectionedViewDataSourceType{
var itemModels: [Element]? = nil
var isInsert = false
var isDelete = true
typealias CellFactory = (UITableView, Int, Element) -> UITableViewCell
var cellFactory: CellFactory
init(cellFactory: @escaping CellFactory) {
self.cellFactory = cellFactory
}
func modelAtIndex(_ index: Int) -> Element? {
return itemModels?[index]
}
func model(at indexPath: IndexPath) throws -> Any {
precondition(indexPath.section == 0)
guard let item = itemModels?[indexPath.item] else {
throw RxCocoaError.itemsNotYetBound(object: self)
}
return item
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return itemModels?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return cellFactory(tableView, indexPath.row, itemModels![indexPath.row])
}
func tableView(_ tableView: UITableView, observedElements: [Element]) {
if self.itemModels?.count ?? 0 > observedElements.count {
self.itemModels = observedElements
}else {
self.itemModels = observedElements
tableView.reloadData()
}
}
}
class FFTableViewReactiveArrayDataSourceSequenceWrapper<S: Sequence>
: FFTableViewReactiveArrayDataSource<S.Iterator.Element>
, RxTableViewDataSourceType {
typealias Element = S
override init(cellFactory: @escaping CellFactory) {
super.init(cellFactory: cellFactory)
}
func tableView(_ tableView: UITableView, observedEvent: Event<S>) {
UIBindingObserver(UIElement: self) { tableViewDataSource, sectionModels in
let sections = Array(sectionModels)
tableViewDataSource.tableView(tableView, observedElements: sections)
}.on(observedEvent)
}
}
extension Reactive where Base: UITableView {
public func items<S: Sequence, Cell: UITableViewCell, O : ObservableType>
(cellIdentifier: String, cellType: Cell.Type = Cell.self)
-> (_ source: O)
-> (_ configureCell: @escaping (Int, S.Iterator.Element, Cell) -> Void)
-> Disposable
where O.E == S {
return { source in
return { configureCell in
let dataSource = FFTableViewReactiveArrayDataSourceSequenceWrapper<S> { (tv, i, item) in
let indexPath = IndexPath(item: i, section: 0)
let cell = tv.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! Cell
configureCell(i, item, cell)
return cell
}
return self.items(dataSource: dataSource)(source)
}
}
}
}
|