You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何弹出Sheet而不遮挡指定视图?

SwiftUI中如何弹出Sheet而不遮挡指定视图?

嘿,我懂你想要的效果——弹出Sheet的时候,底部的菜单还能稳稳露在外面不被遮挡,对吧?SwiftUI默认的Sheet确实会覆盖整个界面,不过咱们有俩实用的办法能解决这个问题👇

方案一:把底部菜单放到更高层级

核心思路是让底部菜单脱离Sheet所在的视图层级,始终处于最上层,这样Sheet就盖不到它了。我们可以把主内容和Sheet拆分到单独视图,然后用外层ZStack把底部菜单叠在最上面:

struct DemoView: View {
    @State var isPresented = true
    
    var body: some View {
        ZStack {
            // 放包含Sheet的主内容
            MainContent(isPresented: $isPresented)
            
            // 底部菜单 - 外层ZStack确保它在Sheet之上
            VStack {
                Spacer()
                Text("My bottom menu")
                    .padding()
                    .background(Color.white)
                    .cornerRadius(8)
                    .padding(.bottom)
            }
        }
    }
}

// 拆分后的主内容视图
struct MainContent: View {
    @Binding var isPresented: Bool
    
    var body: some View {
        ZStack {
            Color.brown
                .ignoresSafeArea()
        }
        .sheet(isPresented: $isPresented) {
            Text("my news page")
                .presentationDetents([.medium, .large]) // 可选:给Sheet加高度选项
        }
    }
}

方案二:自定义Sheet的高度避开菜单

如果不想调整视图层级,我们可以先获取底部菜单的高度,然后让Sheet的底部刚好停在菜单上方。这种方法需要用到GeometryReader来获取菜单尺寸:

struct DemoView: View {
    @State var isPresented = true
    @State private var menuHeight: CGFloat = 0
    
    var body: some View {
        ZStack {
            Color.brown
                .ignoresSafeArea()
            
            VStack {
                Spacer()
                // 用GeometryReader获取菜单的实际高度(含安全区)
                Text("My bottom menu")
                    .padding()
                    .background(Color.white)
                    .cornerRadius(8)
                    .padding(.bottom)
                    .background(
                        GeometryReader { geo in
                            Color.clear
                                .onAppear {
                                    menuHeight = geo.size.height + geo.safeAreaInsets.bottom
                                }
                        }
                    )
            }
        }
        .sheet(isPresented: $isPresented) {
            Text("my news page")
                .padding(.bottom, menuHeight) // 给Sheet内容加底部内边距
                .presentationDetents([.height(UIScreen.main.bounds.height - menuHeight)]) // 固定Sheet高度
                .presentationDragIndicator(.visible) // 显示拖拽指示器
        }
    }
}

两种方案都能实现你要的效果,你可以根据自己的布局需求选一个合适的~

备注:内容来源于stack exchange,提问作者kunass2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 17:09:32