Valerio
Valerio

Reputation: 3617

SwiftUI: strange behavior with onAppear

I'm trying to create a IOS app with SwiftUI that uses NavigationViewand hides the Navigation Bar on the first view (and only on the first one).

So I created an ObservableObject

class NavBarShowViewModel: ObservableObject {
    @Published var isHidden: Bool = true
}

and in my Content View

struct ContentView: View {
    @ObservedObject var navBarShowViewModel = NavBarShowViewModel()

    var body: some View {
        NavigationView {
            Home()
                .navigationBarHidden(self.navBarShowViewModel.isHidden)
        }
        .environmentObject(self.navBarShowViewModel)
    }
}

Now in Home I have:

struct Home: View {
    @EnvironmentObject var navBarShowViewModel: NavBarShowViewModel

    var body: some View {
        VStack {
            HStack {
                NavigationLink(destination: FirstPage()) {
                    Text("Go!")
                }
                
                Text("Hello World")

                Spacer()
            }
            .navigationBarTitle("Home")
        }
        .onAppear(perform: {
            self.navBarShowViewModel.isHidden = true
        })
    }
}

Now FirstPage() has the exact structure of Home(), except that has a different title

 .navigationBarTitle("First Page")

and onAppear has the following code:

.onAppear(perform: {
    self.navBarShowViewModel.isHidden = false
})

With this setup, the app works.

But if inside FirstPage() I navigate further, for example going to SecondPage() (which is for sake of simplicity, identical to FirstPage() with a different title) and then hitting back until I return to Home, onAppear here on Home() is not called, so it shows the navigation bar title.

Could someone explain this?

Upvotes: 2

Views: 764

Answers (1)

Asperi
Asperi

Reputation: 257693

It is about how SwiftUI engine tracks views and if it really appears... anyway, what it is can be determined as it is how child views appear/disappear on navigation stack, so possible solution is to add onDisappear in FirstPage, like

struct FirstPage: View {
    @EnvironmentObject var navBarShowViewModel: NavBarShowViewModel

    var body: some View {

        ... other code here

        .onAppear(perform: {
            self.navBarShowViewModel.isHidden = false
        })
        .onDisappear(perform: {
            self.navBarShowViewModel.isHidden = true
        })
    }
}

Tested with Xcode 12.4 / iOS 14.4

Upvotes: 3

Related Questions