3

假设我们有一个 SwiftUI 视图,其中包含

struct ContentView: View {
    var body: some View {
        TabView {
            FirstView().tabItem {
                // tabItem image and text
            }
            SecondView().tabItem {
                // tabItem image and text
            }
        }
    }
}

现在,假设每个元素都FirstView包含一个NavigationView可滚动的内容NavigationLink。我怎样才能使它在NavigationLink触发目标时(即打开子视图),它接管整个页面(全屏)并隐藏TabView

理想情况下,我想支持 iOS 13+。

我曾尝试遵循Hacking with Swift的指导,但无济于事。

我还遵循了NavigationLink 视图中的 SwiftUI Hide TabView bar中的建议,但发现顶级解决方案的性能并不高,因此我希望能够实现一个没有延迟出现的解决方案。

4

2 回答 2

1

将您的内容包含tabitem在一个检查共享状态的 if 条件中:

struct ContentView: View {

    @StateObject private var state = State()

    var body: some View {
        TabView {
            FirstView().tabItem {
                if !state.hideTabView {
                    // tabItem image and text
                }
            }
            SecondView().tabItem {
                if !state.hideTabView {
                    // tabItem image and text
                }
            }
        }
        .environmentObject(state)
    }
}

State像这样的在哪里ObservableObject

class State: ObservableObject {
    @Published hideTabView: Bool = false
}

然后您可以onAppear在链接到 via 的 View 上使用NavigationLink(例如 inside FirstView):

struct FirstView: View {
    
    @EnvironmentObject private var state: State
    var body: some View {
        VStack {
            // ... some content
        }
        .onAppear(perform: { state.hideTabView = true })
        .onDisappear(perform: { state.hideTabView = false })
    }
}

当您按下“< Back”时,TabView 再次出现会有轻微的延迟,如果这真的让您感到困扰,那么您可以制作一个自定义的后退按钮并将其移动state.hideTabView = false到点击该按钮的事件中。

这是我能想到的一种方法 :) 此外,您可能会发现此线程很有帮助。

于 2021-12-08T19:47:01.183 回答
0

一种解决方案是NavigationView从您的子视图(FirstView 和 SecondView)中删除您的,并NavigationView在您的TabView.

NavigationView {
    TabView {
        //...
    }
}

这适当地将您TabView放在导航堆栈中,而不是作为导航堆栈的父级。这可能会产生不良结果,包括导航栏标题和 UI 更改,因为您将导航堆栈的根向上游移动,但这适用于我的用例。

于 2021-12-08T19:05:54.500 回答