tapされたあとの処理を流れるようにUILabel.textまでメソッドチェーンで書きたい

投稿者: Anonymous
import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
    @IBOutlet weak var buttonB: UIButton!
    @IBOutlet weak var labelB: UILabel!

    let disposeBag = DisposeBag()
    var countVariable = Variable(0)

    override func viewDidLoad() {
        super.viewDidLoad()

        countVariable.asObservable().map{ String($0) }.bind(to: labelB.rx.text).disposed(by: disposeBag)
        buttonB.rx.tap.subscribe(onNext: { [weak self] in
            guard let weakSelf = self else { return }

            weakSelf.countVariable.value = weakSelf.countVariable.value + 1
        }).disposed(by: disposeBag)
    }
}

上記の処理のながれを

tap -> countVariableを1プラスする処理 -> String変換 -> ラベルのテキスト

というように流れるようにメソッドチェーンでつなげて書く方法はありませんでしょうか?

ソースからおわかりと思いますが、
今段階で掲載したソースでメソッドチェーンとして流れるようにつながっているのは、
String変換 -> ラベルのテキストの部分のみです。
流れるようにプログラムが書けるともっとソースが読みやすくなると思っております。

仮に
tap -> countVariableを1プラスする処理 -> String変換 -> ラベルのテキスト
の流れがRx的に不自然なのであれば、流れる順番を修正していただいてかまいません。

解決

RxSwiftの VariableBehaviorSubject (RxSwift4では BehaviorRelay )のラッパーであり、ご質問のソースに書いていただいたような処理をしたい場合には2方向のバインディングを行うのが基本となります。なので、一つのメソッドチェーンでまとめて書くということはできません。

Variableを挟まずに、直接ストリームをつなげるようにすれば一つのメソッドチェーンで書くことができます。

self.buttonB.rx.tap
    .scan(0) { count, _ in count + 1 } // 初期値0に対し、タップのたびに1を足していく
    .map { String($0) }
    .bind(to: self.labelB.rx.text)
    .disposed(by: self.disposeBag)
回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *