我正在尝试创建一个基本的井字游戏,但我无法根据存储游戏状态的模型(嵌套模型)更新视图,我的代码就像以下:
TicTacToeModel存储一个SquareModel数组,SquareModel存储状态为空,叉或零。
因此,我想每次用户按下一个空的正方形来更新我的模型,并使用此模型绘制“ x”或“ o”来更新我的视图
型号:
final class TicTacToeModel: ObservableObject{
@Published var board = [SquareModel]()
@Published var activePlayer = Player.x
init(rowSize: Int) {
self.rowSize = rowSize
for _ in (0 ..< self.rowSize * self.rowSize){
board.append(SquareModel(status: .empty))
}
}
}
class SquareModel: ObservableObject{
@Published var status: Player = .empty
init(status: Player) {
self.status = status
}
}
查看:
struct ContentView: View {
@State var boardModel = TicTacToeModel(rowSize: Definitions().lines)
func getIndex(row:Int, col:Int)-> Int{
return row * Definitions().lines + col
}
func squareAction(index:Int){
self.boardModel.makeMove(index: index, player: self.boardModel.activePlayer)
}
var body: some View {
VStack {
Spacer()
TitleView()
ZStack{
BoardView()
VStack{
ForEach(0..<Definitions().lines) { row in
HStack {
ForEach(0..<Definitions().lines) { col in
ZStack{
SquareView (source: self.$boardModel.board[self.getIndex(row: row, col: col)]){
let index = self.getIndex(row: row, col: col)
self.squareAction(index: index)
}
}
}
}
}
}.aspectRatio(1, contentMode: .fit)
.padding(20)
}
CurrentPlayerView(currentPlayer: self.boardModel.activePlayer)
Spacer()
Button(action: {
self.boardModel.resetGame()
}) {
Text("Restart game!")
.font(.system(size: 30))
.fontWeight(.heavy)
.padding(.horizontal)
}
Spacer()
}.padding(.horizontal)
}
}
struct SquareView: View {
@Binding var source: SquareModel
var action: () -> Void
var body: some View {
xoImageView(player: source.status)
.gesture(TapGesture().onEnded({ () in
self.action()
}))
}
}
注意:模型运行良好,并且可以正确存储所有属性
答案 0 :(得分:0)
ObservableObject/ObservedObject
已调整为MVVM中的一个一级ViewModel桥,其中假定模型为值。因此,自动 不支持ObservableObject
中的分层更新。
因此,将TicTacToeModel
作为ViewModel的一部分,最简单的方法(最好是将SquareModel
的模型从class
更改为struct
下面
struct SquareModel {
var status: Player = .empty
}
因此,SquareModel
中的任何更改都会更新board
中的TicTacToeModel
属性,从而更新视图。