How we can read and write to same ObservableObject in SwiftUI?

Viewed 358

I am making a ObservableObject class and then I am using it for reading and writing value in all app. when I am using my ObservableObject in my StateObject and ObservedObject, they are not the same data, but they are making a different variable in memory, how we can make StateObject and ObservedObject working on a same data?

For example my ObservableObject class has a variable called stringOfText, which as default has No Data! then I make a StateObject variable and start reading default value of stringOfText, then I change the default value of stringOfText and it does not show the update in my ObservedObject! what I am doing wrong?

class TextModel: ObservableObject {
    @Published var stringOfText: String = "No Data!"
}

struct ContentView: View {
    @ObservedObject var readStringOfTextView = TextModel()

    var body: some View {
        TextView()

        Text(readStringOfTextView.stringOfText)
            .foregroundColor(Color.black)
    }
}

struct TextView: View {
    @StateObject var textModel = TextModel()

    var body: some View {
        Text(textModel.stringOfText)
            .padding()
            .foregroundColor(Color.red)

        Button(action: {
            textModel.stringOfText = "Hello, world!"

        }) {
            Text("update string of Text")
                .padding()
        }
    }
}
2 Answers

how we can make StateObject and ObservedObject working on a same data?

You can make it via shared instance, in example:

class TextModel: ObservableObject {
    static let shared = TextModel()     // << here !!

    @Published var stringOfText: String = "No Data!"
}

struct ContentView: View {
    @ObservedObject var readStringOfTextView = TextModel.shared  // << here !!

// ... other code
}

struct TextView: View {
    @StateObject var textModel = TextModel.shared // << here !!

// ... other code
}

You need to pass the TextModel to the child view (use the same instance in both views):

struct ContentView: View {
    @StateObject var readStringOfTextView = TextModel()

    var body: some View {
        TextView(textModel: readStringOfTextView) // pass here

        Text(readStringOfTextView.stringOfText)
            .foregroundColor(Color.black)
    }
}

struct TextView: View {
    @ObservedObject var textModel: TextModel // declare only

    ...
}
Related