SwiftUIでいこう!- スタンフォード大学Lecture 3: MVVM
神経衰弱ゲームを構造を考えながら組み上げていきます。
Model, ViewModel , Viewの3つの構造を作って機能させます。MVVMについては以下のサイトがわかりやすく紹介されています。
このゲームをMVVMで組み上げます。まずViewの役割を持つCntentView()以外の基本的部品を見ていきましょう。
基本の構造
//Model
modelは部品の構造を書き出していきます。今後、この部品を使って画面の表示部分を作っていきます。
import Foundation
struct Game<CardContent>{
var cards:Array<Card>
func choose(card:Card){
}
struct Card{
var isFaceUp:Bool
var isMatched:Bool
var content:CardContent
}
}
//ViewwModel
modelの部品を使って画面を構成する具体的なも機能をつけていきます。
import SwiftUI
class EmojiGame{
private var model:Game<String>
var cards:Array<Game<String>.Card>{
return model.cards
}
}
これらをもとにContentViewで表示するゲームをコントロールできるようにしていきます。
組み立て
実際に使えるようにしていきます。
Modelの"struct Game<CardContent>{}"を使えるように初期化をまず実行できるようにします。init()します
init(numberOfpairOfCards:Int,createCardContent:(Int)->CardContent){
cards = Array<Card>()
for pairIndex in 0..<numberOfpairOfCards{
//処理
}
}ひ
初期化では引数を2つ入れたものを作ります。カードの枚数と中に入れる絵文字を指定しています。
numberOfpairOfCards:Int, createCardContent:(Int)->CardContent
必要な枚数のカードにそれぞれ絵文字をfor 文で入れていきます。
init(numberOfpairOfCards:Int,createCardContent:(Int)->CardContent){
cards = Array<Card>()
for pairIndex in 0..<numberOfpairOfCards{
let content = createCardContent(pairIndex)
cards.append(Card(content: content))
cards.append(Card(content: content))
}
}
cards = Array<Card>()
に追加していきます。神経衰弱にはカードが2枚必要なので、2枚ずつ入れる仕組みを作ります。この時Cardの初期化については以下。
struct Card{
var isFaceUp:Bool=false
var isMatched:Bool=false
var content:CardContent
}
var isFaceUp:Bool=false
var isMatched:Bool=false
として、"init()"する前に初期化しています。("init()"の引数を"content"のみにしてシンプルに)
参考
以下のContentView()の部分で"content"の部分にデータを入れて使えるように作り込みです。
ForEach(emojis[0..<emojicount], id: \.self){emoji in
CardView(content:emoji).aspectRatio(2/3,contentMode:.fit)
}
init()で初期化のコードを書いてViewModelにある
private var model:Game<String>
の部分が書けるようになります。初期化に必要なものはカードの数と絵文字の種類となっています。
"model"での初期化は"必要な数字"と"第一引数を使った関数"となっているので、
let emojis = ["✈️","🐶","🐱","🐻","🚁","🚗","🚇","🚴♀️","🍎","🍌","🍍","🍇","🐢","🐸"]
func createMemoryGame() -> Game<String>{
Game<String>(numberOfpairOfCards:4){pairIndex in
EmojiGame.emojis[pairIndex]
}
}
createMemoryGame()として初期化します。この関数を
var model:Game<String>
に代入します。
private var model:Game<String> = createMemoryGame()
ここの処理は
class EmojiGame{}
の中で定義されているので使うのを限定するためのコードを書きます
static let emojis = ["✈️","🐶","🐱","🐻","🚁","🚗","🚇","🚴♀️","🍎","🍌","🍍","🍇","🐢","🐸"]
static func createMemoryGame() -> Game<String>{
Game<String>(numberOfpairOfCards:4){pairIndex in
EmojiGame.emojis[pairIndex]
}
}
二つのコードに共通な
static
をつけます。これがないとエラーとなります。
最終的なコードはこんな感じになります。
//Model
import Foundation
struct Game<CardContent>{
private(set) var cards:Array<Card>
func choose(card:Card){
}
init(numberOfpairOfCards:Int,createCardContent:(Int)->CardContent){
cards = Array<Card>()
for pairIndex in 0..<numberOfpairOfCards{
let content = createCardContent(pairIndex)
cards.append(Card(content: content))
cards.append(Card(content: content))
}
}
struct Card{
var isFaceUp:Bool=false
var isMatched:Bool=false
var content:CardContent
}
}
//ViewwModel
import SwiftUI
class EmojiGame{
static let emojis = ["✈️","🐶","🐱","🐻","🚁","🚗","🚇","🚴♀️","🍎","🍌","🍍","🍇","🐢","🐸"]
static func createMemoryGame() -> Game<String>{
Game<String>(numberOfpairOfCards:4){pairIndex in
EmojiGame.emojis[pairIndex]
}
}
private var model:Game<String> = createMemoryGame()
var cards:Array<Game<String>.Card>{
return model.cards
}
}
この記事が気に入ったらサポートをしてみませんか?