【问题标题】:NavigationView title doesn't appear when the views are in TabView in SwiftUI当视图在 SwiftUI 中的 TabView 中时,NavigationView 标题不会出现
【发布时间】:2019-12-11 06:06:49
【问题描述】:

我有两个视图,每个视图都包含带有标题的 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)

这样做时,它会显示带有子视图的 TabbarView(),这就是我所看到的: “Travel”(childView 的navigationBarTitle)上方的空间是标签栏的navigationBar,因为我将它推入navigationStack。

【问题讨论】:

    标签: ios swift swiftui navigationview


    【解决方案1】:

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

    此修饰符仅在此视图位于 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 的东西。

    【讨论】:

    • 非常感谢详细的回答和解释这个概念。我明天会实施。再次感谢!
    • 我实现了上面的代码,它工作正常。但是,tabView 中的子视图仍然出现在屏幕中间。就像在“旅行”标题中出现的那样,它实际上应该在几英寸以下。好像标签栏也有导航栏。
    • @OsamaNaeem 我没有同样的问题。你能在你的问题中添加一张画布的图片,这样我就可以看到你指的是什么?
    • 嘿,我刚刚更新了问题。我猜这似乎是一个标签栏被推入导航堆栈。
    • @Andre 在子视图中隐藏标签栏与这个问题没有任何关系。此外,隐藏标签栏是使用 hidesBottomBarWhenPushed 完成的,据我所知,目前 SwiftUI 中不可用。将TabView 嵌套在NavigationView 中并不是允许隐藏标签栏的方法。
    【解决方案2】:

    如果您在 tabview 之前需要 Login/SignUp View,请不要使用 NavigationView 来包装它。在登录/注册视图中

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

    【讨论】:

    • 这样可以,但是当authService.isSignedIn 为true 时,你不会得到动画效果。它只会闪烁到 TabView 中。不可爱。
    • 有没有更好的方法从 Login 导航到 TabView?
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-01
      • 2022-11-21
      • 2020-05-09
      • 2021-12-13
      • 2021-06-14
      • 2019-10-21
      相关资源
      最近更新 更多