暂无描述

UICollectionViewExt+rx.swift 4.3KB

    // // UICollectionViewExt+rx.swift // PaiAi // // Created by LISA on 2017/5/18. // Copyright © 2017年 yb. All rights reserved. // import UIKit import RxSwift import RxCocoa class FFCollectionViewReactiveArrayDataSourceSequenceWrapper<S: Sequence> : FFCollectionViewReactiveArrayDataSource<S.Iterator.Element> , RxCollectionViewDataSourceType { typealias Element = S init(cellFactory: @escaping CellFactory) { super.init() self.cellFactory = cellFactory } func collectionView(_ collectionView: UICollectionView, observedEvent: Event<S>) { UIBindingObserver(UIElement: self) { collectionViewDataSource, sectionModels in let sections = Array(sectionModels) collectionViewDataSource.collectionView(collectionView, observedElements: sections) }.on(observedEvent) } } // Please take a look at `DelegateProxyType.swift` class FFCollectionViewReactiveArrayDataSource<Element> : NSObject, UICollectionViewDataSource , SectionedViewDataSourceType { var itemModels: [Element]? = nil typealias CellFactory = (UICollectionView, Int, Element) -> UICollectionViewCell typealias SupplementaryViewFactory = (UICollectionView, String, IndexPath) -> UICollectionReusableView 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 } var cellFactory: CellFactory var supplementaryViewFactory: SupplementaryViewFactory override init() { // super.init() self.cellFactory = { _, _, _ in return (nil as UICollectionViewCell?)! } self.supplementaryViewFactory = { _, _, _ in (nil as UICollectionReusableView?)! } } // data source func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return itemModels?.count ?? 0 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { return cellFactory(collectionView, indexPath.item, itemModels![indexPath.item]) } func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { return supplementaryViewFactory(collectionView, kind, indexPath) } func collectionView(_ collectionView: UICollectionView, observedElements: [Element]) { self.itemModels = observedElements collectionView.reloadData() collectionView.collectionViewLayout.invalidateLayout() } } extension Reactive where Base: UICollectionView { public func items<S: Sequence, Cell: UICollectionViewCell, O: ObservableType>(cellIdentifier: String, supplementaryIdentifier: String, cellType: Cell.Type = Cell.self) -> (_ source: O) -> (_ configureCell: @escaping (Int, S.Iterator.Element, Cell) -> Void, @escaping (IndexPath, UICollectionReusableView, String) -> Void) -> Disposable where O.E == S { return { source in return { (dataCell,supplement) in let dataSource = FFCollectionViewReactiveArrayDataSourceSequenceWrapper<S>(cellFactory: { (cv, i, item) in let indexPath = IndexPath(item: i, section: 0) let cell = cv.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! Cell dataCell(i, item, cell) return cell }) dataSource.supplementaryViewFactory = { (cv, kind, indexpath) in let view = cv.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: supplementaryIdentifier, for: indexpath) supplement(indexpath, view, kind) return view } return self.items(dataSource: dataSource)(source) } } } }