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

SwiftUI中如何根据视图实际高度设置presentation detents尺寸?

在SwiftUI中动态测量Sheet内容高度并设置presentationDetents

当然可以实现,核心思路是通过**视图偏好(PreferenceKey)**捕获MySheet的实际渲染高度,再动态传递给presentationDetents。这种方式能自动适配辅助功能(如字体放大)导致的视图高度变化,甚至支持内容动态更新时的高度调整。

步骤1:定义捕获高度的PreferenceKey

首先创建一个自定义PreferenceKey,用来传递视图的高度值:

struct ViewHeightKey: PreferenceKey {
    static var defaultValue: CGFloat = 0
    static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
        value = nextValue()
    }
}

步骤2:在MySheet中添加高度测量逻辑

在MySheet的背景中嵌入GeometryReader,通过preference将测量到的高度传递出去:

struct MySheet: View {
    var body: some View {
        // 这里替换成你的Sheet实际内容
        VStack(spacing: 20) {
            Text("自定义Sheet内容")
                .font(.title)
            Text("适配辅助功能设置的动态高度")
                .font(.largeTitle) // 模拟字体放大的情况
            // 更多视图元素...
        }
        .padding()
        .background(
            GeometryReader { proxy in
                Color.clear
                    .preference(key: ViewHeightKey.self, value: proxy.size.height)
            }
        )
    }
}

步骤3:父视图中动态设置presentationDetents

在父视图中捕获传递过来的高度,动态更新presentationDetents的配置:

struct ParentView: View {
    @State private var showSheet = false
    @State private var sheetContentHeight: CGFloat? = nil

    var body: some View {
        Button("打开Sheet") {
            showSheet = true
        }
        .sheet(isPresented: $showSheet) {
            MySheet()
                .onPreferenceChange(ViewHeightKey.self) { newHeight in
                    sheetContentHeight = newHeight
                }
                .presentationDetents(
                    // 优先使用测量到的高度,否则 fallback 到.large
                    sheetContentHeight.map { [.height($0), .large] } ?? [.large]
                )
                .onDisappear {
                    sheetContentHeight = nil // 重置高度,下次打开重新测量
                }
        }
    }
}

关键说明

  • 这种方式会自动跟踪MySheet的布局变化,比如辅助功能调整字体大小、内容动态加载导致高度改变时,都会实时更新detents的高度。
  • 第一次打开Sheet时,可能会先以.large状态显示,待高度测量完成后自动切换到自定义高度,这个过程几乎无感知;如果需要避免初始状态,可以给sheetContentHeight设置一个合理的默认估算值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:40:27