Help us understand the problem. What is going on with this article?

Rxswiftを使ってソートボタンを作る

More than 1 year has passed since last update.

ソートボタンを作った経緯

今回はRxSwiftを使ってソートボタンを作ったのですが、作るのに時間がかかってしまったため他にもソート機能の作り方に悩んでいる方がいれば参考になればと思い書きました。

ソートする値

今回はapiで取ってきたmodelにあるデータに対してソートする機能を作成しました。
startedAtが取得したデータの登録された日付なので、そちらを昇順にしたいと思います。
値のjsonの型としては下記になります。

struct ConnpassStruct: Codable {
    var events: [Events]
    struct Events: Codable {
        var title: String
        var eventUrl: String
        var startedAt: String
        private enum CodingKeys: String, CodingKey {
            case title
            case eventUrl = "event_url"
            case startedAt = "started_at"
        }
    }
}

BehaviorRelay

今回はデータを保持したいのでBehaviorRelayを使いました。
BehaviorRelayにて保持したデータを、ソートボタンのイベントを取得したら
sortメソッドを使って、昇順にします。

self.ascButton.drive(onNext: { _ in
    let ascDate = self.resultsfields.value.sorted(by: {$0.startedAt < $1.startedAt})
    self.resultsfields.accept(ascDate)
}).disposed(by: disposeBag)

参考

RxSwift 再入門
RxCocoa 4 の Signal と Relay のまとめ

Drive

modelで取得したデータをViewModelでsortし、ViewにDriverを使ってbindさせています。
コードとしては下記になります。

viewcontroller.swift
var ascButton: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .fastForward, target: nil, action: nil)

//省略

self.viewModel = ConnpassViewModel(
ascButton: self.ascButton.rx.tap.asDriver(onErrorDriveWith: Driver.empty()),
)

    self.viewModel.ascButton
        .drive(onNext: { [weak self] in
            self?.tableView.reloadData()
        }).disposed(by: disposeBag)
viewmodel.swift
class ViewModel {
    let ascButton: Driver<Void>
    //ここはmodelで取ってきたデータをresultsfieldsにいれているがその記述は省略しています
    var resultsfields = BehaviorRelay<[ConnpassStruct.Events]>(value: [])
    private let disposeBag = DisposeBag()
    init(ascButton: Driver<Void>) {
        self.ascButton.drive(onNext: { _ in
            let ascDate = self.resultsfields.value.sorted(by: {$0.startedAt < $1.startedAt})
            self.resultsfields.accept(ascDate)
        }).disposed(by: disposeBag)
    }
}

参考

RxSwiftでの実装練習の記録ノート(後編)
RxExample MVVM のその先へ(Fat ViewModel の倒し方)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away