Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusing about @EnvironmentObject in SwiftUI

Tags:

swift

swiftui

I'm trying practice @EnvironmentObject tool in SwiftUI.
the share object User init in ContentView.
When I switch from ContentView to NameView work very well.
But, from NameView to AgeView is failed. (take a look error message and Code session, please)

Error message

Fatal error: No ObservableObject of type User found.

Could someone give me advice? Do I miss something? thx

Code

init "User" type in contentView
NavigationView

+-----------+                   +--------+                   +-------+
|ContentView+--NavigationLink-->|NameView+--NavigationLink-->|AgeView|
+-----------+                   +--------+                   +-------+
final class User: ObservableObject {
    @Published var name: String
    @Published var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

struct ContentView: View {
    var user: User = User(name: "SomeName", age: 44)
    var body: some View {
        NavigationView {
            VStack {
                Text("name: \(self.user.name) age: \(self.user.age)")
                NavigationLink(destination: NameView().environmentObject(self.user)) {
                    Text("Show Name")
                }
            }
        }
    }
}

struct NameView: View {
    @EnvironmentObject var user: User
    var body: some View {
        VStack {
            Text("name: \(self.user.name)")
            NavigationLink(destination: AgeView()) {
                Text("Show Age")
            }
        }
    }
}

struct AgeView: View {
    @EnvironmentObject var user: User
    var body: some View {
        VStack {
            Text("age: \(self.user.age)")
        }
    }
}
like image 927
CocoaUser Avatar asked Nov 16 '25 11:11

CocoaUser


1 Answers

Hope this helps you with the following example:

We have our model which is Observable and has all it's variables Published:

class A: ObservableObject {
    @Published var id: String = ""
    @Published var value: String = ""
}

When using it as an EnvironmentObject make sure you'd set this in the SceneDelegate.swift as follows:

let example = Example()

    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = UIHostingController(rootView: example.environmentObject(A()))
        self.window = window
        window.makeKeyAndVisible()
    }

Then we can use this EnvironmentObject in all Views:

struct Example: View {

    @EnvironmentObject var obj: A

    var body: some View {
        Button(action: {
            self.obj.value = "Hi im changed"
        }) {
            Text("Change me")
        }
    }
}

Sometimes when you want to update data in this object, xCode may give you an error about 'No EnvironmentObject set for ... classname etc.', in this case you need to pass an EnvironmentObject to the destination view:

DestinationView().environmentObject(self.A)

Hope this helps, goodluck!

like image 79
Tobias Hesselink Avatar answered Nov 19 '25 08:11

Tobias Hesselink



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!