如何在 SwiftUI 中嵌入 ForEach 的 HStack 中设置相对宽度?
How to set relative width in a HStack embedded in a ForEach in SwiftUI?
我想创建一个属性列表(不使用列表视图)。每个属性都是一个 HStack,其中包含两个文本,名称和值。我希望名称文本始终占整个 HStack 宽度的 30%,而值文本则使用剩余的水平 space。每个属性的高度取决于内容。
我尝试通过以下观点来完成它:
struct FatherList: View {
let attributes: Attributes
init(_ attributes: Attributes) {
self.attributes = attributes
}
var body: some View {
VStack(spacing: CGFloat.spacing.medium) {
ForEach(
attributes,
id: \.name,
content: ChildView.init
)
}
}
}
其中包含以下 ChildView:
struct ChildView: View {
let listItem: Product.Attribute
init(_ attribute: Product.Attribute) {
self.attribute = attribute
}
var body: some View {
GeometryReader { geometry in
HStack(alignment: .top, spacing: 0) {
Text(attribute.name)
.bold()
.frame(width: 0.3 * geometry.size.width)
.background(Color.yellow)
Text(attribute.value)
}
.fixedSize(horizontal: false, vertical: true)
.background(Color.red)
}
}
}
我得到的结果是这样的:
子视图重叠,这不是我想要的,我希望子视图展开并相互跟随。我正在使用 geometryReader 来完成我上面描述的相对宽度。我做错了什么?
这是一个可能的解决方案演示。使用 Xcode 11.4 / iOS 13.4
测试
注:ViewHeightKey
取自
struct ChildView: View {
let attribute: Attribute
@State private var fitHeight = CGFloat.zero
var body: some View {
GeometryReader { geometry in
HStack(alignment: .top, spacing: 0) {
Text(self.attribute.name)
.bold()
.frame(width: 0.3 * geometry.size.width, alignment: .leading)
.background(Color.yellow)
Text(self.attribute.value)
.fixedSize(horizontal: false, vertical: true)
.frame(width: 0.7 * geometry.size.width, alignment: .leading)
}
.background(Color.red)
.background(GeometryReader {
Color.clear.preference(key: ViewHeightKey.self,
value: [=10=].frame(in: .local).size.height) })
}
.onPreferenceChange(ViewHeightKey.self) { self.fitHeight = [=10=] }
.frame(height: fitHeight)
}
}
我想创建一个属性列表(不使用列表视图)。每个属性都是一个 HStack,其中包含两个文本,名称和值。我希望名称文本始终占整个 HStack 宽度的 30%,而值文本则使用剩余的水平 space。每个属性的高度取决于内容。
我尝试通过以下观点来完成它:
struct FatherList: View {
let attributes: Attributes
init(_ attributes: Attributes) {
self.attributes = attributes
}
var body: some View {
VStack(spacing: CGFloat.spacing.medium) {
ForEach(
attributes,
id: \.name,
content: ChildView.init
)
}
}
}
其中包含以下 ChildView:
struct ChildView: View {
let listItem: Product.Attribute
init(_ attribute: Product.Attribute) {
self.attribute = attribute
}
var body: some View {
GeometryReader { geometry in
HStack(alignment: .top, spacing: 0) {
Text(attribute.name)
.bold()
.frame(width: 0.3 * geometry.size.width)
.background(Color.yellow)
Text(attribute.value)
}
.fixedSize(horizontal: false, vertical: true)
.background(Color.red)
}
}
}
我得到的结果是这样的:
子视图重叠,这不是我想要的,我希望子视图展开并相互跟随。我正在使用 geometryReader 来完成我上面描述的相对宽度。我做错了什么?
这是一个可能的解决方案演示。使用 Xcode 11.4 / iOS 13.4
测试注:ViewHeightKey
取自
struct ChildView: View {
let attribute: Attribute
@State private var fitHeight = CGFloat.zero
var body: some View {
GeometryReader { geometry in
HStack(alignment: .top, spacing: 0) {
Text(self.attribute.name)
.bold()
.frame(width: 0.3 * geometry.size.width, alignment: .leading)
.background(Color.yellow)
Text(self.attribute.value)
.fixedSize(horizontal: false, vertical: true)
.frame(width: 0.7 * geometry.size.width, alignment: .leading)
}
.background(Color.red)
.background(GeometryReader {
Color.clear.preference(key: ViewHeightKey.self,
value: [=10=].frame(in: .local).size.height) })
}
.onPreferenceChange(ViewHeightKey.self) { self.fitHeight = [=10=] }
.frame(height: fitHeight)
}
}