将内容直接叠加在导航栏下方

问题描述 投票:0回答:1

我想在 NavigationStack 中的所有视图上覆盖一些内容。我希望将内容直接放置在导航栏下方。在下面的屏幕截图中,这正是我希望黑条的外观和定位在 NavigationStack 中所有视图上的方式:

如何在 iPhone 和 iPad 上以纵向和横向方式完成此操作?看来唯一的方法是确定导航栏和顶部安全区域插图的高度,但我无法让任何东西发挥作用。这样做的目标是在 NavigationStack 中每个视图的顶部显示一个进度条,以便用户可以看到他们在具有多个视图的流程中进展了多远。

屏幕截图显示了使用

.fullScreenCover
呈现的 NavigationStack 中的第一个视图。这是堆栈中第一个视图的代码:

struct NavigationStackEntryView: View {
    @StateObject var viewModel = NavigationStackViewModel()
    @Environment(\.dismiss) var dismiss
    var body: some View {
        NavigationStack {
            ScrollView {
                VStack {
                    // I want this Rectangle to be overlayed on all views in the NavigationStack in this position
                    Rectangle()
                        .frame(height: 10)
                    
                    NavigationLink("Navigate to 2nd view") {
                        SecondView(viewModel: viewModel)
                    }
                }
                .toolbar {
                    ToolbarItem(placement: .automatic) {
                        Button {
                            dismiss()
                        } label: {
                            Text("Cancel")
                        }
                    }
                }
            }
            .navigationTitle("First view")
            .navigationBarTitleDisplayMode(.inline)
            .onAppear {
                print("first view appeared")
            }
        }
    }
}
swiftui overlay swiftui-navigationstack swiftui-scrollview swiftui-navigation
1个回答
0
投票

您可以通过在每个视图上应用覆盖并设置视图内容的偏移量来实现此目的,请参阅示例:

我为此目的创建了一个专用的
View

struct OverlayedView<Content: View>: View {
    @ViewBuilder let content: Content
    
    private let height: CGFloat = 10
    
    var body: some View {
        content
            .frame(maxWidth: .infinity)
            .offset(y: height)
            .overlay(alignment: .top) {
                Rectangle()
                    .frame(height: height)
            }
    }
}

然后您可以按以下方式使用此视图:

struct NavigationStackEntryView: View {
    @StateObject var viewModel = NavigationStackViewModel()
    
    var body: some View {
        NavigationStack {
            OverlayedView {
                ScrollView {
                    VStack {
                        NavigationLink("Navigate to 2nd view") {
                                SecondView(viewModel: viewModel)
                        }
                    }
                    //...
                }
                //...
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.