Home > Blockchain >  Passing one StateObject class of one view to another StateObject class of a different view in SwiftU
Passing one StateObject class of one view to another StateObject class of a different view in SwiftU

Time:09-20

I have two views each with their own class. The first view has an @StateObject of class "DataClass" that initializes a simple struct DataStruct:

 struct View1 : View {
    @StateObject var dataToPass = DataClass()
    
    var body: some View {
        NavigationView{
            ZStack{
                NavigationLink(destination: View2(data: dataToPass)){
                    Text("Navigation Link to View2")
                }
            }
        }
    }
 }

 struct dataStruct {
    var variable1 : String
    var variable2 : String
 }

 class DataClass : ObservableObject {
    var data : dataStruct
    init(){
        data = dataStruct(variable1: "1", variable2: "2")
    }
 }

I'm trying to keep this same instance of the DataClass/dataStruct and pass it on to View2 and its View2Class:

 struct View2: View {
    
    @ObservedObject var data : DataClass
    
    @StateObject var game = View2Class(data: data)
    
    var body: some View {
        Text("Hello")
    }
 }

 class View2Class : ObservableObject {
    @ObservedObject var data : DataClass
    
    init(data : DataClass){
        self.data = data
    }
 }

I want it so that there is only ever one instance/initialization of dataStruct and thus dataClass and View2Class has access to it. View2Class must remain a StateObject. As of right now I am getting an error on the declaration of View2's StateObject: "Cannot use instance member 'data' within property initializer; property initializers run before 'self' is available." I'm sure it is an easy conceptual fix that I am not understanding right now. Thank you!

CodePudding user response:

To fix the error ("Cannot use instance member 'data'...") try something like this:

 struct View1 : View {
    @StateObject var dataToPass = DataClass()
    
    var body: some View {
        NavigationView{
            ZStack{
                NavigationLink(destination: View2(data: dataToPass, game: View2Class(data: dataToPass))){
                    Text("Navigation Link to View2")
                }
            }
        }
    }
 }

 // ...

 struct View2: View {
    @ObservedObject var data: DataClass
    @StateObject var game: View2Class
    
    var body: some View {
        Text("Hello")
    }
 }

CodePudding user response:

You cannot use data to declare game, because data is not "available" before View2 is setup. That is the reason you get the error.

Try this approach, using @Published in the ObservableObject classes, and passing DataStruct from DataClass to your View2Class with a function in .onAppear {...}:

struct DataStruct {
    var variable1: String
    var variable2: String
 }

class DataClass: ObservableObject {
    @Published var data = DataStruct(variable1: "1", variable2: "2")
}

struct View2: View {
    @ObservedObject var dataClass: DataClass
    @StateObject var game = View2Class()
    
    var body: some View {
        Text("Hello")
            .onAppear {
                game.setData(dataClass.data)
            }
    }
}

class View2Class: ObservableObject {
    @Published var data: DataStruct?

    func setData(_ data: DataStruct){
        self.data = data
    }
}
  • Related