当视图位于 SwiftUI 中的 TabView 中时,NavigationView 标题不会出现

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

我有两个视图,每个视图都包含带标题的 NavigationView。我创建了一个 TabBar 视图,它上面还有一个 NavigationView。

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)
}

}

我试过隐藏此视图的导航栏,但没有用。仅显示此视图的导航栏。

这是MainContentView()

struct MainContentView: View {

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

}

知道如何解决这个问题。谢谢!

更新: 基本上,当我点击 Log In 按钮时,我会通过 NavigationLink 传递 TabBarView()。

   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)

这样做时,它显示了具有 child 视图的 TabbarView() 这就是我所看到的: "Travel" 上方的 space(childView 的 navigationBarTitle)是标签栏的 navigationBar,因为我将其推入 navigationStack。

这里首先要指出的是,代码中的所有导航栏修饰符都应该是 NavigationView 内部视图的修饰符,而不是 NavigationView 本身的修饰符。来自 .navigationBarTitle 的文档,例如:

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

此外,不需要 NavigationView 包裹您的 TabView,然后在您的 MainContentView 内包裹另一个。这只会导致嵌套的导航栏,你绝对不希望这样。相反,只需使用一个 NavigationView。我还建议您不要将 NavigationView 放在 MainContentView 正文中。

我重构了您的代码以显示我在说什么,尽管我不确定您在何处尝试使用 .navigationBarBackButtonHidden.navigationBarHidden,因此我省略了它们。请记住,它们的功能就像 .navigationBarTitle - 您需要将它们用作 NavigationView 内视图的修饰符,而不是 NavigationView 本身。

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")
    }
}

您可能会注意到,我还从 .tabItem 中删除了 VStack。您可以将 TextImage 都放在 .tabItem 中而不需要 VStack,如果我没记错的话,.tabItem 会忽略任何不是TextImage 无论如何。

如果您需要 Login/SignUp 在 tabview 之前查看,请不要使用 NavigationView 对其进行包装。在 Login/Sign 向上视图

@EnvironmentObject var authService:AuthService

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

在子视图中,您可以使用 @EnvironmentObject 控制 isSignedIn 变量,并在退出时更改该值 这是之前使用的TabBarView()的例子:

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

这可能是以下选项卡视图之一:

@EnvironmentObject var authService:AuthService

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

这也适用于 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")
            }
            
        }
    }