简体   繁体   中英

NavigationView title doesn't appear when the views are in TabView in SwiftUI

I have two Views and each of them contains NavigationView with title. I have created a TabBar View which also has a NavigationView on it.

struct TabbarView: View {
var body: some View {
    NavigationView{
    TabView {
        MainContentView()
            .tabItem {
                VStack {
                    Text("Main")
                }
        }.tag(0)

        SearchContentView()
            .tabItem {
                VStack {
                    Text("Search")
                }
        }.tag(1)
    }
    }.navigationBarBackButtonHidden(true)
    .navigationBarHidden(true)
}

}

I have tried hiding the navigationBar for this view but that doesn't work. Only the navigation bar of this view appears.

This is MainContentView()

struct MainContentView: View {

var body: some View {
    NavigationView {
        Text("Some Content View")
        }
    .navigationBarTitle("Travel")
}

}

Any idea how to go about this. Thanks!

Update: Basically when I tap on a Log In Button, I am passing TabBarView() through NavigationLink.

   NavigationLink(destination: TabbarView()) {
                        HStack {
                            Text("Log In")
                        }
                        .padding()
                        .frame(width: geometry.size.width - 40, height: 40)
                        .foregroundColor(Color.white)
                        .background(Color.blue)
                        .cornerRadius(5)
                }.padding(.bottom, 40)

In doing that, it shows the TabbarView() with child views this is what I see: The space above "Travel" (navigationBarTitle of the childView) is the navigationBar of the tabbar since I am pushing it into navigationStack.

在此处输入图片说明

The first thing to point out here is that all of the navigation bar modifiers you have in your code should be modifiers on a view inside of the NavigationView , not modifiers on NavigationView itself. From the documentation for .navigationBarTitle , for example:

This modifier only takes effect when this view is inside of and visible within a NavigationView.

Also, there is no need to have a NavigationView wrapping your TabView and then another inside your MainContentView . This will only lead to nested navigation bars, and you definitely don't want that. Instead, just use one NavigationView . I would also suggest that you not put the NavigationView inside the MainContentView body.

I've refactored your code to show what I'm talking about, although I wasn't sure where you were trying to use .navigationBarBackButtonHidden and .navigationBarHidden , so I omitted them. Just keep in mind that they function just like .navigationBarTitle - you need to use them as modifiers on a view inside NavigationView , not on NavigationView itself.

struct TabBarView: View {
    var body: some View {
        TabView {
            NavigationView {
                MainContentView()
            }
                .tag(0)
                .tabItem {
                    Text("Main")
                }

            SearchContentView()
                .tag(1)
                .tabItem {
                    Text("Search")
                }
        }
    }
}
struct MainContentView: View {
    var body: some View {
        Text("Some Content View")
            .navigationBarTitle("Travel")
    }
}

As you might notice, I also removed the VStack from .tabItem . You can put both Text and Image inside .tabItem without the need for a VStack , and if I'm not mistaken, .tabItem ignores anything that is not Text or Image anyway.

If you need Login/SignUp View before tabview do not use NavigationView to wrap it. In the Login/Sign up view

@EnvironmentObject var authService:AuthService

var body: some View{
    ZStack{
        if(!authService.isSignedIn){
            Button(action: {
                self.authService.signIn()
            }) {
                Text("Login")
            }
        }
        else{
            TabBarView()
        }
    }
}

In the subviews you can control the isSignedIn variable with @EnvironmentObject and change that value when Signed Out This is an example of the TabBarView() used before:

var body: some View {
    TabView {
        NavigationView{
            FirstView()
        }
        .tabItem {
            VStack{
                Image("first")
                Text("First")
            }
        }
        NavigationView{
            SecondView()
        }
        .tabItem {
            VStack{
                Image("second")
                Text("Second")
            }
        }
    }
}

This is could be one of the tabviews:

@EnvironmentObject var authService:AuthService

var body: some View {
    TextView("Hello World")
    .navigationBarItems(trailing: LogOutButton(logOutFunction: authService.signOut))
}

This works too in iOS 13:

var body: some View {
        TabView {
            NavigationView {
                FirstTabbarView(viewModel: viewModel)
                    .navigationBarTitle("NavBar title Tabbar1", displayMode: .inline)
            }
            .tabItem {
                Image(systemName: "house.fill")
                Text("Tab bar 1")
            }
            
            NavigationView {
                SecondTabbarView(viewModel: viewModel)
                    .navigationBarTitle("Navbar title Tabbar 2", displayMode: .inline)
            }
            .tabItem {
                Image(systemName: "person.fill")
                Text("Tab bar 2")
            }
            
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM