記事を書こうと思ったきっかけ
MVVM設計でボタンタップを
registerButton.rx.tap.subscribe(onNext: {
viewModel.createUser()
}).disposed(by: disposeBag)
みたいに書いていたんですけどなんかこれってViewModelの責務なんじゃないのかなと思いモヤモヤするので調べてみました。
実装
ViewModelを以下のようにします。
protocol ViewPresentable {
typealias Input = (
buttonTapped: Driver<()>, ()
)
var input: ViewPresentable.Input { get }
}
class ViewModel: ViewPresentable {
var input: ViewPresentable.Input
private let bag = DisposeBag()
init(input: ViewPresentable.Input) {
self.input = input
self.input.buttonTapped.drive(onNext: {
print("tapped")
}).disposed(by: bag)
}
}
次にViewControllerです。
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
private var viewModel: ViewPresentable!
override func viewDidLoad() {
super.viewDidLoad()
viewModel = ViewModel(input: (
buttonTapped: button.rx.tap.asDriver(), ()
))
}
}
これでボタンをタップしてみると
tapped
できました。
ここで重要なのは
inputの
typealias Input = (
buttonTapped: Driver<()>, ()
)
と
viewModel = ViewModel(input: (
buttonTapped: button.rx.tap.asDriver(), ()
))
ですね。
少し成長できた気分です。
UIの更新だけなら最初のやり方でもいいかもしれないですが、ビジネスロジックなども伴う時はこんな感じで書いた方がいいのかな?と思います。
指摘などありましたらよろしくお願いいたします。