如何将 SwiftUI 底部工作表锚定到 ScrollView 内的屏幕底部?

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

我正在使用 SwiftUI 开发一个应用程序,并面临在包含 ScrollView 的视图中定位自定义底部工作表的问题。底部工作表应该锚定到屏幕底部,但它当前锚定到 ScrollView 内容的底部,导致它仅在向下滚动到 ScrollView 末尾后才出现。

这是底页的代码:

struct BottomSheetViewModal<Content: View>: View {
    @Binding var isPresented: Bool
    let content: () -> Content

    var body: some View {
        ZStack(alignment: .bottom) {
            if isPresented {
                Color.black.opacity(0.3)
                    .edgesIgnoringSafeArea(.all)
                    .onTapGesture {
                        isPresented = false
                    }

                content()
                    .background(Color.white)
                    .cornerRadius(16, corners: [.topLeft, .topRight])
                    .padding(.bottom,5)
                    .ignoresSafeArea(.all)
            }
        }
    }
}

extension View {
    func BottomSheetView<Content: View>(
        isPresented: Binding<Bool>,
        @ViewBuilder content: @escaping () -> Content
    ) -> some View {
        ZStack {
            self
            BottomSheetViewModal(isPresented: isPresented, content: content)
        }
    }
}

BottomSheetViewModal 嵌套在 ScrollView 内,这导致工作表的位置位于可滚动内容的底部而不是屏幕的底部。因此,用户必须滚动到滚动视图的底部才能看到完整的底部工作表。

如何将 BottomSheetViewModal 锚定到屏幕底部,而不是 SwiftUI 中 ScrollView 内容的底部?是否有更好的方法来对视图进行分层或使用不同的方法来定位底部工作表,以便无论 ScrollView 的内容大小如何,它始终在屏幕底部可见?

类似于

的css效果
position:fixed;
bottom:0;

任何帮助或建议将不胜感激!

swift swiftui
1个回答
0
投票

我遇到了一个问题,我的自定义底部工作表没有锚定到屏幕底部,而是锚定到 ScrollView 中可滚动内容的底部。经过一番实验,我发现问题的根源在于底部表单相对于 ScrollView 的分层放置。

这是对我有用的解决方案:

问题:当自定义底部工作表嵌套在 ScrollView 内时,它锚定到可滚动内容的底部。

解决方案:通过将自定义底部工作表移动到与 ScrollView 相同的层次级别,该工作表现在可以正确地将其自身定位在屏幕底部,而与可滚动内容无关。

这是演示正确结构的代码:

struct ContentView: View {
    @State private var isSheetPresented = false

    var body: some View {
        ZStack {
            ScrollView {
                // Your scrollable content here
                VStack {
                    ForEach(0..<100) { index in
                        Text("Item \(index)")
                            .padding()
                    }
                }
            }

            // Bottom sheet is placed outside the ScrollView but within the same ZStack
            if isSheetPresented {
                BottomSheetView()
                    .background(Color.white)
                    .cornerRadius(20)
                    .shadow(radius: 10)
                    .frame(height: 300)
                    .edgesIgnoringSafeArea(.all)
            }
        }
        .onTapGesture {
            isSheetPresented.toggle()
        }
    }
}

struct BottomSheetView: View {
    var body: some View {
        VStack {
            Text("This is the bottom sheet content")
                .padding()
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.