如何调整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
相关产品推荐
相关产品推荐

