SwiftUI:如何让HStack随Color.red宽高比变化匹配其宽度?
SwiftUI实现HStack宽度跟随动态宽高比视图的解决方案
现有SwiftUI代码如下,其中红色视图的宽高比由r参数控制,当前下方蓝色HStack的宽度为父容器宽度,需求是调整r时,HStack的宽度始终与红色视图的宽度完全一致。
struct ContentView: View { @State var r:CGFloat = 1 var body: some View { VStack(spacing:0) { Color.red .aspectRatio(r, contentMode: .fit) HStack { Text("LEFT") Spacer() Text("Right") } .frame(height: 40) .background(Color.blue) } } } #Preview { ContentView() }
界面示例:
实现思路
通过SwiftUI的PreferenceKey机制捕获红色视图的实时宽度,将其传递给下方的HStack,强制HStack使用该宽度。
修改后的完整代码
// 定义偏好键,用于传递宽度值 struct WidthPreferenceKey: PreferenceKey { static var defaultValue: CGFloat = 0 static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { value = nextValue() } } struct ContentView: View { @State var r:CGFloat = 1 @State private var redViewWidth: CGFloat = 0 var body: some View { VStack(spacing:0) { Color.red .aspectRatio(r, contentMode: .fit) // 添加背景视图捕获红色视图的宽度 .background( GeometryReader { proxy in Color.clear .preference(key: WidthPreferenceKey.self, value: proxy.size.width) } ) HStack { Text("LEFT") Spacer() Text("Right") } .frame(width: redViewWidth, height: 40) .background(Color.blue) } // 监听偏好键变化,更新存储的宽度值 .onPreferenceChange(WidthPreferenceKey.self) { newValue in redViewWidth = newValue } } } #Preview { ContentView() }
代码说明
WidthPreferenceKey:自定义偏好键,用于在视图层级间传递宽度数值- 红色视图的
background中嵌入GeometryReader,获取自身宽度并通过preference传递 - 父视图通过
onPreferenceChange监听宽度变化,更新redViewWidth状态变量 - HStack的
frame绑定redViewWidth,确保宽度始终与红色视图一致
内容的提问来源于stack exchange,提问作者zumzum
相关产品推荐
相关产品推荐

