SwiftUI中如何让视图与动态尺寸的另一View保持尺寸一致
解决方案
你可以通过 SwiftUI 的 PreferenceKey 捕获图片实际渲染后的高度,再将该高度同步给右侧文本容器即可实现需求,不需要使用会撑满父容器的外层 GeometryReader。
完整适配代码(兼容所有 SwiftUI 版本)
import SwiftUI // 定义PreferenceKey用于存储图片的实际渲染高度 struct ImageHeightKey: PreferenceKey { static var defaultValue: CGFloat = 0 static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { value = nextValue() } } struct TestScreen: View { // 存储动态获取到的图片高度 @State private var imageHeight: CGFloat = 0 var body: some View { VStack { HStack(spacing: 0) { // 左侧图片视图 Image("blue-test-image") .resizable() .scaledToFit() .frame(maxWidth: .infinity) // 读取图片实际高度并存入PreferenceKey .background(GeometryReader { geo in Color.clear.preference(key: ImageHeightKey.self, value: geo.size.height) }) // 右侧文本容器 VStack(spacing: 0) { Text("Some Text") .padding() .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.gray) Text("Other Text") .padding() .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.gray) } // 高度和动态获取的图片高度绑定 .frame(maxWidth: .infinity, maxHeight: imageHeight) } // 监听图片高度变化更新状态 .onPreferenceChange(ImageHeightKey.self) { height in imageHeight = height } Spacer() } .padding() } }
简化版(仅 SwiftUI 4+ 可用)
如果你的项目适配最低版本为 iOS 16+/macOS 13+,可以用自带的 onSizeChange 修饰符省略自定义 PreferenceKey 的步骤:
import SwiftUI struct TestScreen: View { @State private var imageHeight: CGFloat = 0 var body: some View { VStack { HStack(spacing: 0) { Image("blue-test-image") .resizable() .scaledToFit() .frame(maxWidth: .infinity) // 直接读取图片尺寸 .onSizeChange { size in imageHeight = size.height } VStack(spacing: 0) { Text("Some Text") .padding() .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.gray) Text("Other Text") .padding() .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.gray) } .frame(maxWidth: .infinity, maxHeight: imageHeight) } Spacer() } .padding() } }
实现说明
- 去掉外层
GeometryReader避免其默认占满父容器全部可用高度的问题 - 图片设置
scaledToFit会根据自身宽高比和可用宽度自动计算高度,我们通过 PreferenceKey/onSizeChange 拿到这个动态高度 - HStack 内两个子元素都设置
maxWidth: .infinity,会自动平分容器宽度,满足左右宽度相等的要求 - 右侧文本容器高度绑定图片动态高度,两个文本块会自动平分该高度,总高度和图片完全一致
- 无需写死任何固定尺寸,适配任意宽高比的图片
内容的提问来源于stack exchange,提问作者Steffen
相关产品推荐
相关产品推荐

