TabView 中的 NavigationViews 显示不正确

NavigationViews in TabView displayed incorrectly

我正在使用 SwiftUI 并希望构建一个分页 TabView,其中包含两个我可以水平切换的 NavigationView 页面。下面的图片显示了它应该如何工作:

这是我上面例子的代码:

struct ContentView: View {
var body: some View {
    
    TabView {
        Page1()
        
        Page2()
        
    }
    .tabViewStyle(.page)
    
}}

struct Page1: View {
var body: some View {
    NavigationView {
        ScrollView {
            Rectangle()
                .fill(.red)
                .frame(width: 100, height: 100)
        }
        .navigationTitle("Page 1")
    }
    .navigationViewStyle(StackNavigationViewStyle()) 
}}

struct Page2: View {
var body: some View {
    NavigationView {
        ScrollView {
            Rectangle()
                .fill(.blue)
                .frame(width: 100, height: 100)
        }
        .navigationTitle("Page 2")
        
    }
    .navigationViewStyle(StackNavigationViewStyle())
}}

除非有另一种方法,否则 NavigationView 位于 TabView 内很重要,这样如果我向上滚动导航栏标题,就会切换到 .inline,如下所示:

另外,我使用了 StackNavigationViewStyle(),因为如果没有它,当我在它们之间来回切换之前第一次打开应用程序时,页面不会显示。 StackNavigationViewStyle() 解决了这个问题,但问题仍然是,当我第一次打开应用程序时,矩形被错误地放置在屏幕顶部。然后我必须切换到第二页并返回以正确定位它们:

有人知道吗?

一种解决方案是使用选项卡选择参数。最好不要将 StackNavigationViewStyle() 与这些嵌入式 NavigationView 一起使用。您可能使用的是一个选择器,它跟踪您所在的页面和一个存储当前页面的状态变量。这样,NavigationView 就在一个地方,并且为每个 TabView 项目赋予了不同的标题。

struct ContentView: View {
    
    @State private var selectedTab = "1"
    
    var body: some View {
        NavigationView {
            TabView(selection: $selectedTab) {
                Page1()
                    .tag("1")
                    .navigationBarTitle("Page 1")

                Page2()
                    .tag("2")
                    .navigationBarTitle("Page 2")
            }
            .tabViewStyle(.page)
        }
    }
}

struct Page1: View {
var body: some View {
    ScrollView {
        Rectangle()
            .fill(.red)
            .frame(width: 100, height: 100)
    }
}}

struct Page2: View {
var body: some View {
    ScrollView {
        Rectangle()
            .fill(.blue)
            .frame(width: 100, height: 100)
    }
}}

已更新 当你希望 NavigationTitle 在滚动时为 .inline 时,使用以下代码。

struct ContentView: View {
    
    @State private var selectedTab = "1"
    
    var body: some View {
        NavigationView {
            GeometryReader { proxy in
                ScrollView(showsIndicators: false) {
                    TabView(selection: $selectedTab) {
                        Page1()
                            .tag("1")
                            .navigationBarTitle("Page 1")

                        Page2()
                            .tag("2")
                            .navigationBarTitle("Page 2")
                    }
                    .tabViewStyle(.page)
                    .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
                    .frame(height: proxy.size.height)
                    .ignoresSafeArea()
                    
                }
            }
        }
    }
}

struct Page1: View {
    var body: some View {
        VStack {
            Rectangle()
                .fill(.red)
                .frame(width: 200, height: 200)
        }
    }
}

struct Page2: View {
    var body: some View {
        VStack {
            Rectangle()
                .fill(.blue)
                .frame(width: 200, height: 200)
        }
    }
}