SwiftUI -> Thread 1: Fatal error: No observable ob

2020-05-18 23:39发布

问题:

I'm building an app with SwiftUI. When I was trying to display a sheet (previously Modal), this error message appears:

Thread 1: Fatal error: No observable object of type BixiStationCombinedListViewModel.Type found.
A View.environmentObject(_:) for BixiStationCombinedListViewModel.Type may be missing as an ancestor of this view.

This error occurs when I'm using a @State variable to display a modal that includes a Map View using MapKit.

I'm new to Swift Programming and SwiftUI. The error message may be clear for you, but not really for my.

I don't see why and how I should implement a new Environment Object.

Is it because the station I select when taping on the CardView should be stored globally and pass the info to the dedicated view?

The view taking handling the @State

struct CardView: View {

    @EnvironmentObject var bixiModel: BixiStationCombinedListViewModel
    @State private var isModalOpen: Bool = false

    var station: BixiStationCombinedViewModel

    var body: some View {

        ZStack(alignment: .leading) {

                Card()

                StationTextInfo(station: station)

        } .onTapGesture {
            self.isModalOpen = true
            print(self.isModalOpen)
        }
        .sheet(isPresented: self.$isModalOpen) {
            BixiStationDetailView(station: self.station)
        }

    }
}

The view I'm trying to show within the sheet

struct BixiStationDetailView: View {

    @EnvironmentObject var bixiModel: BixiStationCombinedListViewModel

    var station: BixiStationCombinedViewModel

    var body: some View {
        VStack {
            MapView(coordinate: station.coordinate, name: station.name)        
        }
    }
}

Finally the Object

class BixiStationCombinedListViewModel: ObservableObject {

    init() {
        fetchDataFromApi()
    }

    @Published var stationsCombinedList = [BixiStationCombinedViewModel]()

    var stationsInformationList = [BixiStationInformationViewModel]()
    var stationsDataList = [BixiStationDataViewModel]()

    func fetchDataFromApi() {

        }        
    }
}

I can I get ride of the error message and display the proper view?

Thanks all!

回答1:

You have to pass your environment object to BixiStationDetailView, otherwise it won't have anything to bind to its @EnvironmentObject.

.sheet(isPresented: self.$isModalOpen) {
    BixiStationDetailView(station: self.station)
        .environmentObject(self.bixiModel)
}

Since you're presenting BixiStationDetailView as a sheet, it isn't a subview of your CardView and therefore doesn't inherit its @EnvironmentObject.