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

如何调整SwiftUI中.sheet()弹出视图的尺寸?

调整SwiftUI Sheet弹窗尺寸的解决方案

你的问题出在:Sheet的根视图会被系统强制扩展到可用的容器空间,直接在根视图(比如你用的VStack)上添加frame()不会限制弹窗的整体尺寸,因为系统会忽略这个约束。下面是两种有效的解决方法:

方法一:iOS 15+ 官方推荐API(精准控制高度)

从iOS15开始,SwiftUI提供了presentationDetents修饰符,可以直接指定Sheet的展示高度,结合内部视图的宽高约束,就能实现固定尺寸的弹窗:

struct ContentView: View {
    @State private var showingSmallView = false
    var body: some View {
        NavigationView {
            VStack {
                List {
                    Text("hi")
                    Text("hi")
                    Text("hi")
                }
                Button(action: { showingSmallView = true }){
                    Rectangle()
                        .frame(width: 50, height: 50)
                }
            }
        }
        .sheet(isPresented: $showingSmallView){
            smallView()
                .frame(width: 200, height: 200)
                // 指定Sheet的高度为200
                .presentationDetents([.height(200)])
                // 显示拖拽指示器(可选,方便用户调整弹窗高度)
                .presentationDragIndicator(.visible)
        }
    }
}

struct smallView: View {
    var body: some View{
        Text("hda")
            .font(.headline)
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(Color.gray.opacity(0.2))
    }
}

这个方法的优势是完全利用系统API,弹窗行为符合系统规范,在iPad上会自动居中显示固定尺寸的内容,iPhone上则是底部弹出高度为200的弹窗。

方法二:兼容iOS13+ 的通用方案

如果需要支持iOS13及更早版本,可以通过让Sheet根视图填充全屏,再将内容居中并限制尺寸的方式实现:

struct ContentView: View {
    @State private var showingSmallView = false
    var body: some View {
        NavigationView {
            VStack {
                List {
                    Text("hi")
                    Text("hi")
                    Text("hi")
                }
                Button(action: { showingSmallView = true }){
                    Rectangle()
                        .frame(width: 50, height: 50)
                }
            }
        }
        .sheet(isPresented: $showingSmallView){
            ZStack {
                // 透明背景填充整个Sheet
                Color.clear
                    .ignoresSafeArea()
                // 你的内容视图,限制固定尺寸
                smallView()
                    .frame(width: 200, height: 200)
                    .background(Color.white)
                    .cornerRadius(12) // 可选,添加圆角美化
            }
        }
    }
}

struct smallView: View {
    var body: some View{
        Text("hda")
            .font(.headline)
            .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

这个方案的原理是让Sheet的根视图(ZStack)占据全屏,然后将你的内容视图居中放置并限制宽高,视觉上就呈现出缩小的弹窗效果。

内容的提问来源于stack exchange,提问作者Adel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 22:05:07