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

为何设置frame高度60后SwiftUI的viewSize高度仍为0?

问题分析与解决方案

问题根源

你的代码存在布局依赖循环,导致无法正确获取父视图设置的60高度:

  1. viewSize初始值为.zero,你用viewSize.height给Color.red设置frame,直接把Color的高度强制设为0。
  2. onGeometryChange监听的是它前面的视图尺寸,此时它捕获的是高度为0的Color,所以newValue的高度自然是0,进而把viewSize更新为(xxx, 0),形成死循环。
  3. Preview里的.frame(height:60)是给TestGeometryModifierView容器设置的,但内部的Color已经被自身frame限制为0高度,根本不会继承父容器的高度。

修复方案

调整布局顺序,让视图先获取父级分配的空间,再监听尺寸:

struct TestGeometryModifierView: View {
    @State var viewSize:CGSize = .zero
    
    var body: some View {
        Color.red
            // 让Color占满父级可用空间,继承Preview设置的60高度
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .onGeometryChange(for: CGSize.self) { proxy in
                proxy.size
            } action: { newValue in
                viewSize = newValue
                print("View Size \(newValue)")
            }
    }
}

#Preview {
    TestGeometryModifierView()
        .frame(height:60)
}

关键说明

  • Color默认是弹性布局,会尽可能填充父视图的可用空间,去掉内部限制高度的frame,并通过frame(maxWidth: .infinity, maxHeight: .infinity)明确让它占满空间,就能正确继承父容器的60高度。
  • onGeometryChange必须放在视图布局确定之后,才能捕获到最终的实际尺寸,而非初始约束值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 16:24:59