LoginSignup
3
3

More than 3 years have passed since last update.

ControllerとViewModelとのボタンタップのバインディングの試行錯誤

Last updated at Posted at 2019-10-13

前置き

UIViewControllerとViewModelとをバインディングする正攻法の試行錯誤をメモしておく
結論は出てません

パターン1

古来より伝わるIBAction
これだとPresenterの感じがする

class ViewModel {

    func buttonDidTap() {        
    }

}
class ViewController: UIViewController {

    let viewModel: ViewModel = ViewModel()

    @IBAction func buttonDidTap(_ sender: Any) {
        self.viewModel.buttonDidTap()
    }

}

パターン2

ボタンから直接ViewModelのメソッドを呼び出す

class ViewModel {

    @objc func buttonDidTap(_ sender: Any) {
    }

}
class ViewController: UIViewController {

    let viewModel: ViewModel = ViewModel()

    @IBOutlet weak var button: UIButton! {
        didSet {
            self.button.addTarget(self.viewModel,
                                  action: #selector(buttonDidTap(_:)),
                                  for: UIControl.Event.touchUpInside)
        }
    }

}

パターン3 RxSwift

RxSwiftを使ったバインド

import RxCocoa

class ViewModel {

    let buttonDidTap: PublishRelay<Void> = {
        let relay: PublishRelay<Void> = PublishRelay<Void>()
        relay.subscribe(onNext: {
        })
        return relay
    }()

}
import RxSwift

class ViewController: UIViewController {

    let viewModel: ViewModel = ViewModel()

    @IBOutlet weak var button: UIButton! {
        didSet {
            self.button.rx.tap.bind(to: self.viewModel.buttonDidTap)
        }
    }

}

パターン4 ReactiveSwift

import ReactiveSwift
import ReactiveCocoa

class ViewModel {

    let buttonDidTap: CocoaAction<UIButton> = CocoaAction<UIButton>(Action<Void, Any, Never>(execute: {
        return .empty
    }))

}
import ReactiveCocoa

class ViewController: UIViewController {

    let viewModel: ViewModel = ViewModel()

    @IBOutlet weak var button: UIButton! {
        didSet {
            self.button.reactive.pressed = self.viewModel.buttonDidTap
        }
    }

}

パターン5 RxSwift + Action

RxSwiftを使ったバインド

import Action
import RxCocoa

class ViewModel {

    let buttonDidTap = CompletableAction<Void> { _ in
        return Observable<Never>.empty().asCompletable()
    }

}
import Action
import RxSwift

class ViewController: UIViewController {

    let viewModel: ViewModel = ViewModel()

    @IBOutlet weak var button: UIControl! {
        didSet {
            self.button.rx.bind(
                to: self.viewModel.buttonDidTap,
                controlEvent: self.button.rx.controlEvent(UIControl.Event.touchUpInside),
                inputTransform: { _ in () }
            )
        }
    }

}
3
3
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
3
3