RxSwiftのVariableをUICollectionViewにbindしつつサイズや余白も適用する
欲張りな子ね。
前準備
・Empty Projectをつくる
・一旦閉じて、ターミナルで該当ディレクトリ開いて pod init
・RxSwift入れてxcworkspace開く
・Main.storyboardにUICollectionViewをブッこんで、ViewControllerとIBOutletで接続
コード
import UIKit import RxSwift import RxCocoa class DataSource: NSObject, RxCollectionViewDataSourceType, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { struct Element { let numbers: [Int] } var numbers: [Int] = [] private let disposeBag = DisposeBag() private let collectionView: UICollectionView init(collectionView: UICollectionView) { self.collectionView = collectionView super.init() self.collectionView.rx.setDelegate(self).disposed(by: disposeBag) } func collectionView(_ collectionView: UICollectionView, observedEvent: Event<DataSource.Element>) { guard case .next(let entity) = observedEvent else { return } numbers = entity.numbers collectionView.reloadData() } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { return collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return numbers.count } @objc(collectionView:layout:sizeForItemAtIndexPath:) func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: 88, height: 88) } @objc(collectionView:layout:insetForSectionAtIndex:) func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { return UIEdgeInsetsMake(10, 10, 10, 10) } } class ViewController: UIViewController { private let disposeBag = DisposeBag() @IBOutlet weak var collectionView: UICollectionView! let variable = Variable<[Int]>(Array(0...100)) var dataSource: DataSource! override func viewDidLoad() { super.viewDidLoad() dataSource = DataSource(collectionView: collectionView) variable.asObservable() .map { DataSource.Element(numbers: $0) } .asDriver(onErrorDriveWith: Driver.empty()) .drive(collectionView.rx.items(dataSource: dataSource)) .disposed(by: disposeBag) } }
↑これが参考になった。
素直にRxDataSourcesでも使えばいいのかもしれないけど、 ほげほげ.drive(collectionView.rx.items(...
のやつでViewModelからバインドするにはデリゲートを切る必要があるっぽくて、バインドしつつデリゲートメソッドも生きる方法は今のところこれかなーって感じ。
DataSourceがDelegateを担ってるのアレかもしれないけどどっちもView層だしまあ多少はね?
RxSwiftむずかしい!けどたのしい(^ω^)