Home > Net >  How to pass data into sub view that the sub view can not change
How to pass data into sub view that the sub view can not change

Time:01-23

I am very new to Swift and SwiftUI and trying to work out how to achieve the following.

  1. ContentView creates two User objects (player and cpu)
  2. ContentView passes those objects to a sub view ScoreView
  3. ScoreView should print properties from User (eg score and name)
  4. ScoreView needs to be updated when User.score changes

This is what I have so far, and it works. However I am concerned that since there is a @Binding attached to the variable in ScoreView it could change the values. I would prefer this view to have these values as read only.

class User: ObservableObject {
    var name: String
    @Published var score: Int
    
    init(name: String, score: Int) {
        self.name = name
        self.score = score
    }
}
struct ContentView: View {
    
    @StateObject var player = User(name: "Player", score: 0)
    @StateObject var cpu = User(name: "CPU", score: 0)
    
    var body: some View {
        ZStack {
            Image("background-plain").resizable().ignoresSafeArea()
            VStack {
                Spacer()
                Image("logo")
                Spacer()
                HStack {
                    Spacer()
                    ScoreView(name: $player.name, score: $player.score)
                    Spacer()
                    ScoreView(name: $cpu.name, score: $cpu.score)
                    Spacer()
                }
                .fontWeight(.semibold)
                .foregroundColor(.white)
                Spacer()
            }
        }
    }
}
struct ScoreView: View {
    
    @Binding var name: String
    @Binding var score: Int
    
    var body: some View {
        VStack {
            Text(name)
                .font(.headline)
                .padding(.bottom, 10)
            Text(String(score))
                .font(.largeTitle)
        }
    }
}

CodePudding user response:

Replace

@Binding var

With

let

Then remove the $ from the parent, where the two connect.

You should also change your User to a value type.

struct User {
    var name: String
    var score: Int
    
    init(name: String, score: Int) {
        self.name = name
        self.score = score
    }
}
  • Related