SwiftUI中如何让.sheet从顶部而非底部可拖动?
SwiftUI Sheet 能否设置为从顶部拖动?
原生的.sheet组件没办法直接改成从顶部拖动——它基于系统底层的Sheet实现,默认只支持从底部向上弹出,没有提供修改弹出方向的API。不过你可以通过自定义实现来模拟这个效果,下面是一个简单的SwiftUI原生方案:
自定义顶部弹出Sheet示例
struct TopDownSheetView: View { @Binding var isPresented: Bool let content: () -> View var body: some View { GeometryReader { geo in ZStack { // 点击背景关闭Sheet Color.black.opacity(0.3) .onTapGesture { withAnimation(.easeInOut) { isPresented = false } } // 顶部滑下的Sheet内容 VStack { content() } .frame(width: geo.size.width, height: geo.size.height * 0.6) .background(Color.white) .cornerRadius(16, corners: [.bottomLeft, .bottomRight]) .offset(y: isPresented ? 0 : -geo.size.height) // 添加向下拖动关闭的手势 .gesture( DragGesture() .onEnded { value in if value.translation.height > 50 { withAnimation(.easeInOut) { isPresented = false } } } ) } .ignoresSafeArea() } } } // 使用方式 struct MyView: View { @State private var showTopSheet = false var body: some View { Button("弹出顶部Sheet") { withAnimation(.easeInOut) { showTopSheet = true } } .fullScreenCover(isPresented: $showTopSheet) { TopDownSheetView(isPresented: $showTopSheet) { Text("顶部弹出的Sheet") .font(.title) .padding() } } } }
实现说明
- 用
fullScreenCover作为容器,不用自己处理视图层级和遮罩的显示逻辑 - 通过
offset控制Sheet的位置:弹出时从顶部滑到屏幕内,收起时滑回顶部 - 添加拖动手势,向下拖动超过50pt的阈值就触发关闭动画
- 点击背景遮罩也能关闭Sheet,符合常规交互习惯
内容的提问来源于stack exchange,提问作者DevB2F
相关产品推荐
相关产品推荐

