How to reference with SwiftUI EnvironmentObject

Viewed 2751

According to the Apple Official guide I'm guessing if each view just has one environmentObject then doing that would be fine. When there happened to be more than one, I'm not sure how the object are referenced.

struct LandmarkList: View {
    @EnvironmentObject private var userData: UserData
...
 ForEach(userData.landmarks) { landmark in
                    if !self.userData.showFavoritesOnly || landmark.isFavorite {
                        NavigationLink(
                            destination: LandmarkDetail(landmark: landmark)
                                .environmentObject(self.userData)

                        ) {
                            LandmarkRow(landmark: landmark)
                        }
                    }
                }

Above is the code in apple's official guide where in LandMarkDetail file

struct LandmarkDetail: View {
    @EnvironmentObject var userData: UserData

I am wondering how is the environmentObject in LandMarkList referenced to the environment object in LandmarkDetail. Are they binded? I added a second EnvironmentObject in the file but nothing happened

struct LandmarkDetail: View {
    @EnvironmentObject var userData: UserData
    @EnvironmentObject var testData: UserData

So how to reference to each of the userData and testData

Edit: I tried to add environment object in following file:

import SwiftUI

struct LandmarkList: View {
    @EnvironmentObject private var userData: UserData
    @EnvironmentObject private var testData: TestData
    var body: some View {
        NavigationView {
            List {
                Toggle(isOn: $userData.showFavoritesOnly) {
                    Text("Show Favorites Only")
                }
                Toggle(isOn: $testData.testbool) {
                                   Text("Test")
                }
...
struct LandmarksList_Previews: PreviewProvider {
    static var previews: some View {
        ForEach(["iPhone SE", "iPhone XS Max"], id: \.self) { deviceName in
            LandmarkList()
                .previewDevice(PreviewDevice(rawValue: deviceName))
                .previewDisplayName(deviceName)
        }
        .environmentObject(UserData())
        .environmentObject(TestData())
    }
}
final class TestData: ObservableObject {
    @Published var testbool = false
}

The preview crashed. Xcode could compile but immediately gives following error

Fatal error: No ObservableObject of type TestData found.
A View.environmentObject(_:) for TestData may be missing as an ancestor of this view.: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/Monoceros_Sim/Monoceros-30.4/Core/EnvironmentObject.swift, line 55
2019-10-12 19:07:46.565707+0800 Landmarks[13034:643289] Fatal error: No ObservableObject of type TestData found.
A View.environmentObject(_:) for TestData may be missing as an ancestor of this view.: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/Monoceros_Sim/Monoceros-30.4/Core/EnvironmentObject.swift, line 55
1 Answers

don't forget to do this in Scenedelegate to bind your object:

window.rootViewController = UIHostingController(rootView: contentView.environmentObject(TestData()).environmentObject(UserData()))
Related