5

I am fairly new to SwiftUI and ran into the following problem:

I have a model that contains some integer values like so:

class Game: ObservableObject {

    @Published var ownScore:Int = 0
    @Published var opponentScore:Int = 0

    ... some methods
}

I also need a view to display these scores and get updated whenever any of these values change. I would need something along the lines of this, however, this doesn't work since the values are published integers.

struct ScoreView: View {
    @EnvironmentObject var game: Game
    @State var displayOpponent: Bool

    var body: some View {
        VStack {
            if displayOpponent {
                Text("Opponent Score")
                Text("Score: \(game.$opponentScore)")
            } else {
                Text("Your Score")
                Text("Score: \(game.$ownScore)")
            }

        }
    }
}

Any ideas on how to implement this correctly?

Tobilence
  • 115
  • 1
  • 6

2 Answers2

5

Use in Text just properties, on published they will be updated automatically

struct ScoreView: View {
    @EnvironmentObject var game: Game
    @State var displayOpponent: Bool

    var body: some View {
        VStack {
            if displayOpponent {
                Text("Opponent Score")
                Text("Score: \(game.opponentScore)")   // no $ 
            } else {
                Text("Your Score")
                Text("Score: \(game.ownScore)")        // no $
            }

        }
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
0

Your Game object needs to be instantiated as an @ObservedObject not an @EnvironmentObject unless you are injecting it into the environment somewhere not shown in your code, so...

class Game: ObservableObject {

    @Published var ownScore:Int = 0
    @Published var opponentScore:Int = 0
}

struct ContentView: View {
    @ObservedObject var game = Game()
    @State var displayOpponent: Bool = true

    var body: some View {
        VStack {
            if displayOpponent {
                Text("Opponent Score")
                Text("Score: \(game.opponentScore)")
            } else {
                Text("Your Score")
                Text("Score: \(game.ownScore)")
            }
        }
    }
}

...would work. Also you are simply presenting the values of the published variables so the $ isn't required.

Magnas
  • 3,832
  • 5
  • 33
  • 48
  • 1
    @Chris Yes, but only if you have already inserted the Game object into the environment in an ancestor view as I stated in my answer. – Magnas Apr 09 '20 at 11:06