SwiftUI 在 NavigationLink 视图中隐藏 TabView 栏

2024-03-22

我为每个选项卡项目都有一个 TabView 和单独的 NavigationView 堆栈。它工作得很好,但是当我打开任何 NavigationLink 时,TabView 栏仍然显示。我希望每当我单击任何导航链接时它就会消失。

struct MainView: View {
    @State private var tabSelection = 0

    var body: some View {
        TabView(selection: $tabSelection) {
            FirstView()
                .tabItem {
                    Text("1")
                }
                .tag(0)
            SecondView()
                .tabItem {
                    Text("2")
                }
                .tag(1)
        }
    }
}

struct FirstView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: FirstChildView()) { // How can I open FirstViewChild with the TabView bar hidden?
                Text("Go to...")
            }
            .navigationBarTitle("FirstTitle", displayMode: .inline)
        }
    }
}

我找到了将 TabView 放入 NavigationView 中的解决方案,因此在单击 NavigationLink 后,TabView 栏被隐藏。但这会弄乱选项卡项的 NavigationBarTitles。

struct MainView: View {
    @State private var tabSelection = 0

    var body: some View {
        NavigationView {
            TabView(selection: $tabSelection) {
                ...
            }
        }
    }
}

struct FirstView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: FirstChildView()) {
                Text("Go to...")
            }
            .navigationBarTitle("FirstTitle", displayMode: .inline) // This will not work now
        }
    }
}

使用此解决方案,每个 TabView 项具有不同的 NavigationTabBar 的唯一方法是使用嵌套的 NavigationView。也许有一种方法可以正确实现嵌套的导航视图? (据我所知,导航层次结构中应该只有一个 NavigationView)。

如何在 SwiftUI 中正确隐藏 NavigationLink 视图内的 TabView 栏?


我真的很喜欢上面发布的解决方案,但我不喜欢 TabBar 没有根据视图转换隐藏这一事实。 实际中,当使用tabBar.isHidden时向左滑动导航回来时,结果是不可接受的。

我决定放弃原生 SwiftUI TabView 并编写自己的代码。 UI 中的结果更加美观:

以下是用于达到此结果的代码:

首先定义一些视图:

struct FirstView: View {
    var body: some View {
        NavigationView {
            VStack {
                Text("First View")
                    .font(.headline)
            }
            .navigationTitle("First title")
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
            .background(Color.yellow)
        }
    }
}

struct SecondView: View {
    var body: some View {
        VStack {
            NavigationLink(destination: ThirdView()) {
                Text("Second View, tap to navigate")
                    .font(.headline)
            }
        }
        .navigationTitle("Second title")
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
        .background(Color.orange)
    }
}

struct ThirdView: View {
    var body: some View {
        VStack {
            Text("Third View with tabBar hidden")
                .font(.headline)
        }
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
        .background(Color.red.edgesIgnoringSafeArea(.bottom))
    }
}

然后,创建 TabBarView (这将是您的应用程序中使用的根视图):

struct TabBarView: View {
    enum Tab: Int {
        case first, second
    }
    
    @State private var selectedTab = Tab.first
    
    var body: some View {
        VStack(spacing: 0) {
            ZStack {
                if selectedTab == .first {
                    FirstView()
                }
                else if selectedTab == .second {
                    NavigationView {
                        VStack(spacing: 0) {
                            SecondView()
                            tabBarView
                        }
                    }
                }
            }
            .animation(nil)
            
            if selectedTab != .second {
                tabBarView
            }
        }
    }
    
    var tabBarView: some View {
        VStack(spacing: 0) {
            Divider()
            
            HStack(spacing: 20) {
                tabBarItem(.first, title: "First", icon: "hare", selectedIcon: "hare.fill")
                tabBarItem(.second, title: "Second", icon: "tortoise", selectedIcon: "tortoise.fill")
            }
            .padding(.top, 8)
        }
        .frame(height: 50)
        .background(Color.white.edgesIgnoringSafeArea(.all))
    }
    
    func tabBarItem(_ tab: Tab, title: String, icon: String, selectedIcon: String) -> some View {
        ZStack(alignment: .topTrailing) {
            VStack(spacing: 3) {
                VStack {
                    Image(systemName: (selectedTab == tab ? selectedIcon : icon))
                        .font(.system(size: 24))
                        .foregroundColor(selectedTab == tab ? .primary : .black)
                }
                .frame(width: 55, height: 28)
                
                Text(title)
                    .font(.system(size: 11))
                    .foregroundColor(selectedTab == tab ? .primary : .black)
            }
        }
        .frame(width: 65, height: 42)
        .onTapGesture {
            selectedTab = tab
        }
    }
}

该解决方案还允许在 TabBar 中进行大量自定义。 例如,您可以添加一些通知徽章。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SwiftUI 在 NavigationLink 视图中隐藏 TabView 栏 的相关文章

随机推荐

  • Margin-Top 将外部 div 向下推

    我有一个标题 div 作为包装 div 中的第一个元素 但是当我向标题 div 内的 h1 添加上边距时 它会将整个标题 div 向下推 我意识到每当我将上边距应用于页面上的第一个可见元素时就会发生这种情况 这是一个示例代码片段 谢谢 di
  • Javascript:无法播放wav文件

    基于 StackExchange 的代码 我编写了打开 wav 文件的代码 wav 文件本身是一个有效的文件 因为它可以与我的 Python 程序一起正常播放 但 javascript 函数不起作用 声音文件与我的 html 文件位于同一文
  • Content-Id header的精确格式

    当谈到格式时我真的很困惑Content Id消息部分中的标头 在我看来 只有RFC 2045 https www rfc editor org rfc rfc2045 section 7涵盖了标头的格式 但很简短 在构建高级用户代理时 可能
  • 构造函数内部与外部的 JavaScript 类属性

    我正在努力理解在构造函数内部和外部定义属性之间的区别 在下面的示例中 两个属性都可以以相同的方式在实例上访问 有什么区别 class Foo constructor this bar 1 baz 1 const foo new Foo co
  • CloudKit 在不同 iCloud 帐户之间共享数据,但并非与所有人共享数据

    在我的应用程序中 我想通过 iCloud 与其他 iCloud 用户共享数据 但不是与全世界共享数据 而是与选定的其他 iCloud 用户共享数据 我想过一种可行的方法 但我不确定它是否可行 以及我是否忘记或误解了一些事情 假设用户 A 希
  • CakePHP 2.x Containable 内的 GROUP BY

    我正在疯狂地尝试找到一个好的解决方案 要么使用set extract 或者其他的东西 我想在我的容器中添加一个 GROUP BY params array conditions gt array Project id gt ProjectI
  • PHP - 使用 ADBDB 同时连接到同一服务器上的两个数据库

    是否可以使用 PHP 5 3 ADODB5 SQL Server 2008 在同一服务器上打开与两个模式的连接 这就是我正在尝试的 Connect to users database connUsers NewADOConnection m
  • 使用 NSPersistentStoreCoordinator 的要点是什么?

    在核心数据讲座中斯坦福193P http www stanford edu class cs193p cgi bin drupal iTunes 上的 iPhone 课程 讲师使用 Core Data 编写了一个示例项目 而没有使用NSPe
  • Hibernate二级缓存-打印结果

    我使用 Cache 注释在应用程序中定义了二级缓存 我正在使用 findById 查询 如下所示 long id 4 Company cmp companyDAO findById id 其中 Company 是我从数据库获得的对象 如何检
  • Spring Boot 和 Ehcache - 多 CacheException

    我正在尝试向 springboot 应用程序添加缓存 但遇到了启动过程中引发 org ehcache jsr107 MultiCacheException 异常的问题 我正在使用以下内容 全部通过 Maven pom 文件加载 Spring
  • Python - 什么时候可以使用 os.system() 发出常见的 Linux 命令

    从另一个线程中分离出来 什么时候适合使用 os system 发出 rm rf cd make xterm ls 等命令 考虑到上述命令有模拟版本 make 和 xterm 除外 我假设使用这些内置 python 命令而不是使用 os sy
  • Seaborn:ValueError:调色板='jet'否

    从seaborn运行以下示例docs https seaborn pydata org generated seaborn boxplot html有论据palette jet import seaborn as sns tips sns
  • 金字塔资源:简单的英语

    我一直在阅读对新创建的金字塔应用程序实施授权 和身份验证 的方法 我不断遇到 资源 这个概念 我在应用程序中使用 python couchdb 根本不使用 RDBMS 因此没有 SQLAlchemy 如果我像这样创建一个 Product 对
  • 为什么说malloc()和printf()是不可重入的?

    在 UNIX 系统中我们知道malloc 是不可重入函数 系统调用 这是为什么 相似地 printf 也被认为是不可重入的 为什么 我知道可重入的定义 但我想知道为什么它适用于这些函数 是什么阻止了它们保证可重入 malloc and pr
  • Cassandra 种子节点和连接到节点的客户端

    我对 Cassandra 种子节点以及客户端如何连接到集群有点困惑 我似乎在文档中找不到这一点信息 客户端是否仅包含种子节点列表 并且每个节点委托一个新主机供客户端连接 种子节点是否真的仅用于节点到节点的发现 而不是客户端的特殊节点 每个客
  • 如何捕获发送到模拟的参数?

    有谁知道如何捕获发送到 OCMock 对象的参数 id mock OCMockObject mockForClass someClass NSObject captureThisArgument mock expect foo
  • 如何从 onBind 函数获取尝试绑定我的服务的应用程序包名称或 UID?

    我在一个应用程序中有一个服务 我可以从不同的应用程序访问该服务 当应用程序尝试绑定此服务时 我想知道哪个应用程序正在尝试在 onBind 函数中绑定我的服务 但我无法在 onBind 函数中获取该应用程序的包名称或 UID 是否可以获取尝试
  • 使用 MPJ Express 发送对象

    我是并行编程的新手 我想用 java 来完成它 我想知道是否可以通过 MPI 发送和接收更复杂的对象 我用的是 MPJ Express 然而 每当我想发送一个对象时 我都会收到 ClassCastException MPI Init arg
  • 如何使用 vscode:// 链接打开文件

    我想像phpstorm一样使用vscode ide链接 我知道我们可以phpstorm open file filepath line line 如何使用vscode达到同样的效果 多谢 这个链接 vscode file file line
  • SwiftUI 在 NavigationLink 视图中隐藏 TabView 栏

    我为每个选项卡项目都有一个 TabView 和单独的 NavigationView 堆栈 它工作得很好 但是当我打开任何 NavigationLink 时 TabView 栏仍然显示 我希望每当我单击任何导航链接时它就会消失 struct