问题描述
我正在尝试在 SwiftUI 中创建一个视图,其中左侧图像的背景应根据右侧文本的高度垂直缩放.
I am trying to create a view in SwiftUI where the background of the image on the left should scale vertically based on the height of the text on the right.
我尝试了很多不同的方法,从 GeometryReader
到 .layoutPriority()
,但我没有设法让它们中的任何一个工作.
I tried a lot of different approaches, from GeometryReader
to .layoutPriority()
, but I haven't managed to get any of them to work.
当前状态:
期望状态:
我知道我可以通过对我发布的示例的 .frame(100)
进行硬编码来模仿该功能,但是由于右侧的文本是动态的,所以这行不通.
I know that I could imitate the functionality by hardcoding the .frame(100)
for the example I posted, but as text on the right is dynamic, that wouldn't work.
这是截图中视图的完整代码:
This is full code for the view in the screenshot:
import SwiftUI
struct DynamicallyScalingView: View {
var body: some View {
HStack(spacing: 20) {
Image(systemName: "snow")
.font(.system(size: 32))
.padding(20)
.background(Color.red.opacity(0.4))
.cornerRadius(8)
VStack(alignment: .leading, spacing: 8) {
Text("My Title")
.foregroundColor(.white)
.font(.system(size: 13))
.padding(5)
.background(Color.black)
.cornerRadius(8)
Text("Dynamic text that can be of different leghts. Spanning from one to multiple lines. When it's multiple lines, the background on the left should scale vertically")
.font(.system(size: 13))
}
}
.padding(.horizontal)
}
}
struct DailyFactView_Previews: PreviewProvider {
static var previews: some View {
DynamicallyScalingView()
}
}
推荐答案
这里是一个基于视图首选项键的解决方案.使用 Xcode 11.4/iOS 13.4 测试
Here is a solution based on view preference key. Tested with Xcode 11.4 / iOS 13.4
struct DynamicallyScalingView: View {
@State private var labelHeight = CGFloat.zero // << here !!
var body: some View {
HStack(spacing: 20) {
Image(systemName: "snow")
.font(.system(size: 32))
.padding(20)
.frame(minHeight: labelHeight) // << here !!
.background(Color.red.opacity(0.4))
.cornerRadius(8)
VStack(alignment: .leading, spacing: 8) {
Text("My Title")
.foregroundColor(.white)
.font(.system(size: 13))
.padding(5)
.background(Color.black)
.cornerRadius(8)
Text("Dynamic text that can be of different leghts. Spanning from one to multiple lines. When it's multiple lines, the background on the left should scale vertically")
.font(.system(size: 13))
}
.background(GeometryReader { // << set right side height
Color.clear.preference(key: ViewHeightKey.self,
value: $0.frame(in: .local).size.height)
})
}
.onPreferenceChange(ViewHeightKey.self) { // << read right side height
self.labelHeight = $0 // << here !!
}
.padding(.horizontal)
}
}
struct ViewHeightKey: PreferenceKey {
static var defaultValue: CGFloat { 0 }
static func reduce(value: inout Value, nextValue: () -> Value) {
value = value + nextValue()
}
}
这篇关于在 SwiftUI 中根据文本高度自动调整视图高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!