SwiftUI 在 NavigationLink 视图中隐藏 TabView 栏

人气:741 发布:2022-10-16 标签: ios swiftui swift swiftui-tabview swiftui-navigationview

问题描述

我有一个 TabView 和每个 Tab 项的单独 NavigationView 堆栈.它运行良好,但是当我打开任何 NavigationLink 时,仍会显示 TabView 栏.我希望它在我点击任何 NavigationLink 时消失.

struct MainView: View {@State 私有变量 tabSelection = 0var主体:一些视图{TabView(选择:$tabSelection){第一视图().tabItem {文本1")}.tag(0)第二视图().tabItem {文本(2")}.tag(1)}}}struct FirstView:查看{var主体:一些视图{导航视图{NavigationLink(destination: FirstChildView()) {//如何在隐藏 TabView 栏的情况下打开 FirstViewChild?Text("转到...")}.navigationBarTitle("FirstTitle", displayMode: .inline)}}}

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

struct MainView: View {@State 私有变量 tabSelection = 0var主体:一些视图{导航视图{TabView(选择:$tabSelection){...}}}}struct FirstView:查看{var主体:一些视图{导航视图{NavigationLink(目的地:FirstChildView()){Text("转到...")}.navigationBarTitle("FirstTitle", displayMode: .inline)//现在不行了}}}

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

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

解决方案

可能的解决方案可以基于我在

struct FirstTabView:查看{@State private var tabBar:UITabBar!= 零var主体:一些视图{导航视图{NavigationLink(目的地:第一个子视图().onAppear { self.tabBar.isHidden = true }//!!.onDisappear { self.tabBar.isHidden = false }//!!){Text("转到...")}.navigationBarTitle("FirstTitle", displayMode: .inline)}.background(TabBarAccessor { tabbar in//<< here !!self.tabBar = 标签栏})}}

注意:或者当然,如果 FirstTabView 应该是可重用的并且可以独立实例化,那么 tabBar 里面的属性应该是可选的并显式处理 ansbsent tabBar.

I have a TabView and separate NavigationView stacks for every Tab item. It works well but when I open any NavigationLink the TabView bar is still displayed. I'd like it to disappear whenever I click on any NavigationLink.

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

I found a solution to put a TabView inside a NavigationView, so then after I click on a NavigationLink the TabView bar is hidden. But this messes up NavigationBarTitles for Tab items.

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

With this solution the only way to have different NavigationTabBars per TabView item, is to use nested NavigationViews. Maybe there is a way to implement nested NavigationViews correctly? (As far as I know there should be only one NavigationView in Navigation hierarchy).

How can I hide TabView bar inside NavigationLink views correctly in SwiftUI?

解决方案

The possible workaround solution can be based on TabBarAccessor from my answer on Programmatically detect Tab Bar or TabView height in SwiftUI

Here is a required modification in tab item holding NavigationView. Tested with Xcode 11.4 / iOS 13.4

struct FirstTabView: View {
    @State private var tabBar: UITabBar! = nil

    var body: some View {
        NavigationView {
            NavigationLink(destination:
                FirstChildView()
                    .onAppear { self.tabBar.isHidden = true }     // !!
                    .onDisappear { self.tabBar.isHidden = false } // !!
            ) {
                Text("Go to...")
            }
            .navigationBarTitle("FirstTitle", displayMode: .inline)
        }
        .background(TabBarAccessor { tabbar in   // << here !!
            self.tabBar = tabbar
        })
    }
}

Note: or course if FirstTabView should be reusable and can be instantiated standalone, then tabBar property inside should be made optional and handle ansbsent tabBar explicitly.

934