【问题标题】:Update view in SwiftUI using nested models使用嵌套模型在 SwiftUI 中更新视图
【发布时间】:2020-02-11 08:12:09
【问题描述】:

我正在尝试创建一个基本的井字游戏作为练习,但我无法根据存储游戏状态的模型(嵌套模型)更新我的视图,我的代码就像以下:

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()
        }))
    }
}

注意:模型工作正常并正确存储所有属性

【问题讨论】:

    标签: swift data-binding swiftui


    【解决方案1】:

    ObservableObject/ObservedObject 被调整为 MVVM 中的一级 ViewModel 桥,其中模型被假定为值。所以ObservableObject 内的分层更新不支持自动

    因此,将TicTacToeModel 视为 ViewModel 的一部分,最简单且更可取的方法是将模型(SquareModel)从class 更改为struct,如下所示

    struct SquareModel {
        var status: Player = .empty
    }
    

    因此,SquareModel 中的任何更改都将更新 TicTacToeModel 中的 board 属性,从而更新视图。

    【讨论】:

      猜你喜欢
      • 2021-03-23
      • 2021-08-11
      • 1970-01-01
      • 2021-06-01
      • 1970-01-01
      • 2017-04-10
      • 1970-01-01
      • 1970-01-01
      • 2021-05-14
      相关资源
      最近更新 更多