見出し画像

【Swift】RxDataSourcesを使ってみた。

はじめに


RxSwift学習中のHanagasakiです。UITableViewのデータバインディングについて、深堀したいと感じたので、動画や技術記事を拝見し学んだことを纏めました。

使用環境


● OS:macOS Big Sur 11.3.1
● Xcode:13.2.1
● Swift:5.4
● RxSwift:6.5.0
● RxCocoa:6.5.0
● RxDataSources:5.0.0

RxDataSourcesって?


RxDataSourcesRxSwiftの性質を持ったUITableViewUICollectionViewDataSourceのライブラリです。

RxDataSourcesを使いたい理由は、UITableViewUICollectionViewのデータバインディングが容易に出来るからです。

つまり、UIイベントの受け取り(delete、insert、move)がこのライブラリを使うことで、簡単に実装が出来るということです。

ソースコード


今回、ソースコードのみでUIを作成したので、.storyboardファイルと.xibファイルは説明しません。

ViewController.swift

//  ViewController.swift

import UIKit
import RxSwift
import RxCocoa
import RxDataSources

class ViewController: UIViewController {

    /// セクションとセルの値を入れる。
    var items = BehaviorRelay(value:
                                [SectionModel(header: "今季",
                                              items: [Anime(name: "明日ちゃんのセーラ服")])])
    
    let disposeBag = DisposeBag()
    
    /// テーブルビュー
    let tableView: UITableView = {
        let tableView = UITableView()
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        return tableView
    }()
    
    /// セル
    let cell: UITableViewCell = {
        let cell = UITableViewCell()
        return cell
    }()
    
    /// データソース
    let dataSource = RxTableViewSectionedReloadDataSource<SectionModel>(configureCell: {
        ds, tv, ip, item in
        let cell = tv.dequeueReusableCell(withIdentifier: "cell", for: ip)
        cell.textLabel?.text = item.name
        cell.tintColor = .black
        return cell
    },
    titleForHeaderInSection: {
        ds, index in
        return ds.sectionModels[index].header
    })
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(tableView)
        lauout()
        setupTableView()
    }
    
    /// データバインディング
    func setupTableView() {
        items
            .bind(to: tableView.rx.items(dataSource: dataSource))
            .disposed(by: disposeBag)
    }

    /// tableViewのレイアウトを調整。
    func lauout() {
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.backgroundColor = .white
        tableView.separatorColor = .black
        tableView.separatorInset = .zero
        let top = tableView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0)
        let trailing = tableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0)
        let leading = tableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0)
        let bottom = tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0)
        NSLayoutConstraint.activate([leading, trailing, top, bottom])
    }
    
}

Anime.swift

//  Anime.swift

import Foundation

struct Anime {
    var name: String
}

SectionModel.swift

//  SectionModel.swift

import Foundation
import RxDataSources

struct SectionModel {
    var header: String
    var items: [Anime]
}

extension SectionModel: SectionModelType {
    init(original: SectionModel, items: [Anime]) {
        self = original
        self.items = items
    }
}

完成したUI


図1.完成した画面

ViewController.swiftの変数items配下のSectionModelの値を加えれば、UI側に反映されます。

var items = BehaviorRelay(value:
                                [SectionModel(header: "今季",
                                              items: [Anime(name: "明日ちゃんのセーラ服")])])

おわりに


最後まで読んで下さり、ありがとうございます。
今回は、RxDataSourcesでオブジェクトライブラリを使わずに、データバインディングしてみました。

慣れていないと読みにくいですが、慣れて仕舞えばソースコードのみで、UIイベントの受け取りが出来る様になるので、是非、使ってみて下さい。

参考文献


この記事が気に入ったらサポートをしてみませんか?