RxSwift+MVVMのお勉強?数字を暗記するゲーム
ちゃんとMVVMになっていると思うのだがどうだろうか
Inputs: UIEvent(ボタンのタップ、ViewDidLoad)
outputs: Viewがタップできるか、解答中の数字文字列、問題の数字等
ViewModelのデータの変更をViewが反映できている。
ViewModelは問題のデータや結果をGameManager(Model)的な存在とやり取りをしている。
またViewModelはstateというView(ゲーム)の状態を管理する
[Inputs]
protocol MemoryGameViewModelInputs { func numberTapped(num: Int) func passButtonTapped() func clearButtonTapped() func viewDidLoad() }
①各ボタンをタップした時 ボタンがタップされる(view) 数字を追加するもしくは一文字削除する(viewModel) viewが更新される。
②viewDidLoadでViewModel内でもゲームを開始したい。
[outputs]
protocol MemoryGameViewModelOutputs { var targetString: Observable<String> { get set } var currentAnswerString: Observable<String> { get set } var result: Observable<GudgeResult> { get } var tapEnabled: Observable<Bool> { get } var gameFinished: Observable<Void> { get } }
① targetString 問題が始まるときに更新され、ViewのLabelとbindする。
②currentAnswerString 入力中の文字列。ボタンのタップで更新され、Viewに反映される。
③result 答えあわせ時に更新される。結果がViewに反映される。
④tapEnabled 問題表示中と結果を表示中(stateが.showTarget, .gudgeResult)の時はタップを制限したい。
⑤gameFinished ゲームが終了した時に一度だけ流したいイベント。結果の画面に移動する。
viewModel.outputs .nextTargetString .bind(to: showTargetNumberForWhile) .disposed(by: bag) viewModel.outputs .currentAnswerString .bind(to: label.rx.text) .disposed(by: bag) viewModel.outputs .result .bind(to: showResultThenRequest) .disposed(by: bag) viewModel.outputs .tapEnabled .bind(to: baseView.rx.isActive) .disposed(by: bag) viewModel.outputs .gameFinished .bind(to: showGameResultVC) .disposed(by: bag)
[state]
enum MemoryGameState { case showTarget //問題を表示する。 case trySolving //解答する case gudgeResult //答え合わせをする。 }
このゲームの流れとして ①showTarget 問題を一定時間表示 --> ボタンのタップを制限、1秒表示して ②へ
②trySolving 入力を受け付ける。数字やクリア、パスなどを受け付ける。 必要長さの回答を得られた場合に -> ③へ
③gudgeResult 結果を判定しViewが更新される。(正解または間違っている部分を表示する 。) Viewがn秒間結果を表示し終えると ①へと更新する。