Yousif Ismat
Yousif Ismat

Reputation: 31

Nested view crashes when trying to update EnvironmentObject value

I want to hide and unhide the tab bar in the root view of my app using other views. I have used environment object for it, however when i try to update the value of environment object the preview crashes.

here is a step by step; i have a class that conforms to the ObservableObject class that has one property, isPresent.

final class TabBarPresenter: ObservableObject {
    @Published var isPresent: Bool = true
    
    func updatePresentState() {
        isPresent.toggle()
    }
}

In the root view where i swap some views using the tab bar, i have declared the TabBarPresenter:

struct RootView: View {
    
    @State var selectedTab: Int = 0
    @StateObject var tabBarPresenter = TabBarPresenter()
    
    init() {
        UITabBar.appearance().isHidden = true
    }
    
    var body: some View {
        ZStack {
            TabView(selection: $selectedTab) {
                HomeView()
                    .tag(0)
                
                //unrelated code...
            }
            
            //unrelated code...
        }
        .environmentObject(tabBarPresenter)
    }
}

and have passed down the object using the environmentObject modifier.

in another view where I show some details, I want to hide the tab bar so this is what I did:

struct DetailsView: View {
    
    @StateObject private var viewModel = DetailsViewModel()
    
    var body: some View {
        GeometryReader {}
        .onAppear { viewModel.tabBarPresenter.updatePresentState() }
        .toolbar(.hidden)
    }

}

struct DetailsView_Previews: PreviewProvider {
        
    static var previews: some View {
        DetailsView()
            .preferredColorScheme(.dark)
            .environmentObject(TabBarPresenter())
    }
}

i try to change the isPresent value when the view appears, but the preview crashes, furthermore, here is the code for DetailsViewModel:

final class DetailsViewModel: ObservableObject {
    @EnvironmentObject var tabBarPresenter: TabBarPresenter
}

and finally, i call the DetailsView inside the HomeView (which itself is in the root view), here is the code for the HomeView:

struct HomeView: View {
    
    @StateObject private var viewModel = HomeViewModel()
    
    var body: some View {
        NavigationStack {
            ZStack {...}
            .navigationDestination(isPresented: $viewModel.presentDetailsView) {
                DetailsView()
            }
        }
        .toolbar(.hidden, for: .bottomBar)
        
    }

Upvotes: 0

Views: 109

Answers (0)

Related Questions