0

I got 3 views, the main view is MyTabView, and I would like to hide the TabBar when I navigate to a subview, and I define a class to store config which called TabBarConfig, and I pass it to subviews using EnvironmentObject. But when I change the data inside the class in subview, the TabBar doesn't hide, and it shows a purple warning read that "Accessing StateObject's object without being installed on a View. This will create a new instance each time", Here's the codes:



class TabBarConfig: ObservableObject {
    @Published var hideTabBar: Bool = false
}

struct MyTabView: View {
    @ObservedObject var tabBarConfig = TabBarConfig()
    @State private var selectedItem = 0

    init() {
        UITabBar.appearance().isHidden = self.tabBarConfig.hideTabBar
    }

    var body: some View {
        TabView(selection: $selectedItem) {
            HomeView()
                .tabItem {
                    Image(systemName: "house.fill")
                    Text("Home")
                }
                .tag(0)
            UserView()
                .tabItem {
                    Image(systemName: "person.fill")
                    Text("User")
                }
                .tag(1)
        }
        .environmentObject(self.tabBarConfig)
    }
}

struct HomeView: View {
    @EnvironmentObject var tabBarConfig: TabBarConfig
    @State var showSubView: Bool = false

    var body: some View {
        NavigationView {
            NavigationLink(destination: SubView(), isActive: $showSubView) {
                Button(action: {
                    showSubView = true
                }, label: {
                    Text("Go To SubView")
                })
            }
            .environmentObject(self.tabBarConfig)
        }
    }
}

struct SubView: View {
    @EnvironmentObject var tabBarConfig: TabBarConfig

    var body: some View {
        VStack {
            Text("Some Text")
        }
        .onAppear {
            self.tabBarConfig.hideTabBar = true
        }
    }
}

Hope you can help me out.

leo
  • 82
  • 1
  • 6
  • 1
    I don't believe the code you've shown represents the issue (have you tried it in a blank project to see?). The only thing "wrong" here is that you should be using `StateObject` instead of `ObservedObject` for an `ObservableObject` owned by the `View`. – jnpdx Jan 02 '23 at 03:49
  • @jnpdx I tried this in a blank project, it didn't work out as well – leo Jan 02 '23 at 04:11
  • @jnpdx I found that when the variable changed in the class, it doesn't call the init function – leo Jan 02 '23 at 04:19
  • I'm not sure what that last comment means – jnpdx Jan 02 '23 at 04:25
  • I add a line of code: `print(self.tabBarConfig.hideTabBar)` and it doesn't print when the data in that Observable class is changed – leo Jan 02 '23 at 04:27
  • You shouldn't be doing things like that in `init` -- use `onChange` on `onReceive` to do side effects. You may want to watch "Demystifying SwiftUI" from WWDC for info on why. – jnpdx Jan 02 '23 at 04:36
  • change the observedobject to stateobject as the first comment, and you remove .environmentObject(self.tabBarConfig) from homeview – andylee Jan 02 '23 at 05:43
  • Does this answer your question? [SwiftUI hide TabBar in subview](https://stackoverflow.com/questions/58444689/swiftui-hide-tabbar-in-subview) – lazarevzubov Jan 02 '23 at 05:58

0 Answers0