Contents 非表示
実装
Storyboard
CounterViewModel.swift (ロジック)
import RxSwift
import RxCocoa
protocol CounterViewModelInputs {
var increment: PublishRelay<Void> { get }
var decrement: PublishRelay<Void> { get }
var reset: PublishRelay<Void> { get }
}
protocol CounterViewModelOutputs {
var counterValue: Driver<Int> { get }
}
protocol CounterViewModelType {
var inputs: CounterViewModelInputs { get }
var outputs: CounterViewModelOutputs { get }
}
class CounterViewModel: CounterViewModelType, CounterViewModelInputs, CounterViewModelOutputs {
var inputs: CounterViewModelInputs { return self }
var outputs: CounterViewModelOutputs { return self }
// Inputs
let increment = PublishRelay<Void>()
let decrement = PublishRelay<Void>()
let reset = PublishRelay<Void>()
// Outputs
let counterValue: Driver<Int>
// Properties
private let _counterValue = BehaviorRelay<Int>(value: 0)
private let disposeBag = DisposeBag()
init() {
increment
.withLatestFrom(_counterValue)
.map { $0 + 1 }
.bind(to: _counterValue)
.disposed(by: disposeBag)
decrement
.withLatestFrom(_counterValue)
.map { $0 - 1 }
.bind(to: _counterValue)
.disposed(by: disposeBag)
reset
.map { 0 }
.bind(to: _counterValue)
.disposed(by: disposeBag)
counterValue = _counterValue
.asDriver(onErrorJustReturn: 0)
.distinctUntilChanged()
}
}
HomeViewController.swift (メインのView)
import UIKit
import RxSwift
import RxCocoa
class HomeViewController: UIViewController {
@IBOutlet private weak var counterLabel: UILabel!
@IBOutlet private weak var incrementLabel: UIButton!
@IBOutlet private weak var decrementLabel: UIButton!
@IBOutlet private weak var resetLabel: UIButton!
private let viewModel: CounterViewModelType = CounterViewModel()
private let disposeBag = DisposeBag()
// MARK: - View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
bind()
}
}
private extension HomeViewController {
func bind() {
incrementLabel.rx.tap
.bind(to: viewModel.inputs.increment)
.disposed(by: disposeBag)
decrementLabel.rx.tap
.bind(to: viewModel.inputs.decrement)
.disposed(by: disposeBag)
resetLabel.rx.tap
.bind(to: viewModel.inputs.reset)
.disposed(by: disposeBag)
viewModel.outputs.counter
.map { String($0) }
.drive(counterLabel.rx.text)
.disposed(by: disposeBag)
}
}