0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【RxSwift】UICollectionViewのbindについて

Posted at

はじめに

RxSwiftでCollectionViewを使用する際のバインド方法がいくつかあることを知り、簡単にまとめてみました。

開発環境

Xcode 13.3
Swift 5.6
RxSwift 6.5.0

UICollectionViewのbindについて

バインドパターン1

items.bind(to: collectionView.rx.items)でデータをバインド
indexPathをIndexPath(row: row, section: 0)としてセルを生成して返す

    let items = Observable.just([1, 2, 3])
         
    items.bind(to: collectionView.rx.items) { (collectionView, row, element) in
        let indexPath = IndexPath(row: row, section: 0)
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! NumberCell
        cell.value?.text = "\(element) @ \(row)"
        return cell
    }.disposed(by: disposeBag)

バインドパターン2

items.bind(to: collectionView.rx.items(cellIdentifier: "Cell", cellType: NumberCell.self))でCellを指定しながらデータをバインド

    let items = Observable.just([1, 2, 3])
         
    items.bind(to: collectionView.rx.items(cellIdentifier: "Cell", cellType: NumberCell.self)) { (row, element, cell) in
        cell.value?.text = "\(element) @ \(row)"
    }.disposed(by: disposeBag)

バインドパターン3

変換を実行するために使用されるカスタムデータを使用して、items.bind(to: collectionView.rx.items(dataSource: dataSource))でバインド

    let dataSource = RxCollectionViewSectionedReloadDataSource<SectionModel<String, Double>>()

    let items = Observable.just([
             SectionModel(model: "First section", items: [1.0, 2.0, 3.0]),
             SectionModel(model: "Second section", items: [1.0, 2.0, 3.0]),
             SectionModel(model: "Third section", items: [1.0, 2.0, 3.0])])

    dataSource.configureCell = { (dataSource, cv, indexPath, element) in
        let cell = cv.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! NumberCell
        cell.value?.text = "\(element) @ row \(indexPath.row)"
        return cell
    }

    items
        .bind(to: collectionView.rx.items(dataSource: dataSource))
        .disposed(by: disposeBag)

セル選択時の処理

collectionView(_:didSelectItemAtIndexPath:)と同じ

    collectionView.rx.itemSelected
        .subscribe(onNext: { [unowned self] indexPath in
            self.collectionView.deselectItem(at: indexPath, animated: true)
            // ここに追加
        })
        .disposed(by: disposeBag)

delegateの設定

通常のデリゲートとリアクティブデリゲートを併用できるようになる

UICollectionViewDelegate,UICollectionViewDelegateFlowLayout
UIScrollView+Rx
    public func setDelegate(_ delegate: UIScrollViewDelegate) -> Disposable {
        return RxScrollViewDelegateProxy.installForwardDelegate(delegate, retainDelegate: false, onProxyForObject: self.base)
    }
UICollectionViewDataSource
UICollectionView+Rx
    public func setDataSource(_ dataSource: UICollectionViewDataSource) -> Disposable {
        RxCollectionViewDataSourceProxy.installForwardDelegate(dataSource, retainDelegate: false, onProxyForObject: self.base)
    }

おわりに

整理してみると大したことではなさそうなので、基本的には1番分かりやすい(collectionView(_:cellForItemAt:)に近い)パターン1で実装していけば良いかと思いました。

参照

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?