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

macOS下SwiftUI .sheet视图尺寸调整异常问题

SwiftUI Sheet 动态内容尺寸异常问题解决

问题代码

import SwiftUI

struct ContentView: View {
    @State private var showModal = false
    @State private var hmm = true
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, world!")
        }
        .padding()
        .sheet(isPresented: $showModal) {
            VStack {
                Button {
                    hmm.toggle()
                } label: {
                    Image(systemName: "plus")
                }
                if hmm {
                    VStack {
                        Text("Some Text")
                        Text("Some Text")
                        Text("Some Text")
                        Text("Some Text")
                        Text("Some Text")
                    }
                }
            }.padding()
        }
        .toolbar {
            Button {
                showModal = true
            } label: {
                Image(systemName: "plus")
            }
        }
    }
}

问题现象

  • Sheet初始弹出时尺寸正常:
    sheet初始正常尺寸
  • 点击按钮隐藏文本后,Sheet尺寸能正确缩小:
    隐藏文本后尺寸正常
  • 再次点击按钮显示文本时,Sheet尺寸无法适配新增内容,出现异常:
    显示文本后尺寸异常

解决方法

方法1:用ScrollView包裹Sheet内容

给Sheet里的动态内容套一层ScrollView,让SwiftUI能正确感知内容高度变化,同时还能在内容过多时支持滚动:

.sheet(isPresented: $showModal) {
    ScrollView {
        VStack {
            Button {
                hmm.toggle()
            } label: {
                Image(systemName: "plus")
            }
            if hmm {
                VStack {
                    Text("Some Text")
                    Text("Some Text")
                    Text("Some Text")
                    Text("Some Text")
                    Text("Some Text")
                }
            }
        }.padding()
    }
}

方法2:给动态内容设置布局优先级

给显示/隐藏的文本区域添加layoutPriority,让SwiftUI优先计算这部分内容的尺寸,确保Sheet能正确更新:

if hmm {
    VStack {
        Text("Some Text")
        Text("Some Text")
        Text("Some Text")
        Text("Some Text")
        Text("Some Text")
    }
    .layoutPriority(1)
}

方法3:手动设置首选内容尺寸

监听hmm的变化,手动控制Sheet的preferredContentSize,这种方式需要手动计算高度,适合对尺寸有精准要求的场景:

.sheet(isPresented: $showModal) {
    VStack {
        Button {
            hmm.toggle()
        } label: {
            Image(systemName: "plus")
        }
        if hmm {
            VStack {
                Text("Some Text")
                Text("Some Text")
                Text("Some Text")
                Text("Some Text")
                Text("Some Text")
            }
        }
    }
    .padding()
    .onChange(of: hmm) { newValue in
        // 根据实际内容调整高度数值
        let targetHeight = newValue ? 220 : 60
        UIApplication.shared.windows.first?.rootViewController?.preferredContentSize = CGSize(width: UIScreen.main.bounds.width * 0.8, height: targetHeight)
    }
}

推荐优先尝试方法1,既解决尺寸问题又提升了内容过多时的用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:17:21