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

SwiftUI中GeometryReader报告尺寸异常问题咨询

问题:GeometryReader返回的宽高数值异常(高度大于宽度)

我使用GeometryReader获取视图尺寸时,返回的宽度和高度明显不符合预期——高度居然大于宽度。相关代码如下:

GeometryReader { geometry in
    Image(systemName: "photo")
        .resizable()
        .scaledToFit()
        .overlay(
            Text("Width: \(Int(geometry.size.width)), Height: \(Int(geometry.size.height))").foregroundStyle(.white)
        )
}

问题截图:
问题截图


解决方法

问题核心是你读取的是GeometryReader自身的尺寸,而非内部Image的实际渲染尺寸。GeometryReader的尺寸由它的父容器决定(比如屏幕可用空间),虽然Image通过scaledToFit()缩放到适应容器,但你输出的是容器的大小,不是图片的真实尺寸。

方法1:直接在Image的overlay内嵌套GeometryReader

把GeometryReader放到Image的overlay内部,这样获取的就是Image实际渲染后的尺寸:

Image(systemName: "photo")
    .resizable()
    .scaledToFit()
    .overlay {
        GeometryReader { imgGeometry in
            Text("Width: \(Int(imgGeometry.size.width)), Height: \(Int(imgGeometry.size.height))")
                .foregroundStyle(.white)
        }
    }

方法2:用PreferenceKey传递尺寸(适合复杂场景)

如果需要在视图其他位置复用这个尺寸,可以通过PreferenceKey来传递:

首先定义一个PreferenceKey:

struct SizePreferenceKey: PreferenceKey {
    static var defaultValue: CGSize = .zero
    static func reduce(value: inout CGSize, nextValue: () -> CGSize) {}
}

然后在视图中使用:

@State private var imageSize: CGSize = .zero

Image(systemName: "photo")
    .resizable()
    .scaledToFit()
    .background {
        GeometryReader { geo in
            Color.clear
                .preference(key: SizePreferenceKey.self, value: geo.size)
        }
    }
    .onPreferenceChange(SizePreferenceKey.self) { newSize in
        imageSize = newSize
    }
    .overlay(
        Text("Width: \(Int(imageSize.width)), Height: \(Int(imageSize.height))")
            .foregroundStyle(.white)
    )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 06:03:15