SwiftUI: как переключить ведущего предупреждения при изменении ViewModel - PullRequest
1 голос
/ 03 августа 2020

У меня на SwiftUI простая игра. Это представление (с важными частями для ясности).

struct MainScreen: View {
    @ObservedObject var game = GameEngine()

    @State var gameOver = false

    var body: some View {
        NavigationView {
            ZStack {
                Color.backgroundGray.edgesIgnoringSafeArea(.all)

                // MARK: - Screen Content
                VStack {
                }
            }
            .sheet(isPresented: $showLeader) { LeaderBoard(game: game) }
            .alert(isPresented: $gameOver) {
                Alert(title: Text("Game Over"),
                      message: Text("There are no more moves available."),
                      dismissButton: .default(Text("OK"), action: {
                        self.game.resetGame(boardSize: boardSize)
                        if game.state == .won {
                            self.showLeader.toggle()
                        }
                      }))
            }

Класс GameEngine () имеет опубликованное состояние, которое является перечислением. Я хочу изменить свойство MainScreen @State всякий раз, когда свойство GameEngine State имеет значение .won или .over, но я не могу понять, как правильно это наблюдать. Это свойство изменяется в модели всякий раз, когда меняется игровая ситуация, поэтому его не следует изменять в представлении.

enum State {
    case start
    case won
    case running
    case over
}

@Published var state: State = .running {
    didSet {
        switch state {
        case .over:
            print("game over")
        case .won:
            let record = Record(playerName: playerName, score: score)
            leaderBoard.append(record)
            defaults.set(highest, forKey: "High Score")
        case .start:
            print("started")
        case .running:
            print("running")
        }
    }
}

1 Ответ

0 голосов
/ 03 августа 2020

Вы можете использовать onReceive:

NavigationView {
    ...
}
.onReceive(game.$state) { state in 
    if [.won, .over].contains(state) {
        self.gameOver = true
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...