使用嵌套模型更新SwiftUI中的视图
我试图创建一个基本的tic-tac-toe游戏作为练习,但我无法根据存储游戏状态的模型(嵌套模型)更新我的视图,我的代码如下所示: TictoeModel存储SquareModel数组,SquareModel存储空、交叉或无状态 因此,每当用户按下一个空方块时,我想更新我的模型,并使用这个模型绘制“x”或“o”来更新我的视图 型号:使用嵌套模型更新SwiftUI中的视图,swift,data-binding,swiftui,Swift,Data Binding,Swiftui,我试图创建一个基本的tic-tac-toe游戏作为练习,但我无法根据存储游戏状态的模型(嵌套模型)更新我的视图,我的代码如下所示: TictoeModel存储SquareModel数组,SquareModel存储空、交叉或无状态 因此,每当用户按下一个空方块时,我想更新我的模型,并使用这个模型绘制“x”或“o”来更新我的视图 型号: final class TicTacToeModel: ObservableObject{ @Published var board = [SquareM
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))
}
}
}
视图:
注意:模型运行良好,并正确存储所有属性
observeObject/ObservedObject
被调整为MVVM中的一级ViewModel桥,其中模型被假定为值。因此,observateObject
中的分层更新不受自动支持
因此,考虑到TicTacToeModel
作为视图模型的一部分,最简单的方法,也是最好的方法是将模型(即SquareModel
)从class
更改为struct
,如下所示
struct SquareModel {
var status: Player = .empty
}
因此,SquareModel
中的任何更改都将更新更新视图的TicTacToeModel
中的board
属性
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()
}))
}
}
struct SquareModel {
var status: Player = .empty
}