【问题标题】:How to set relative width in a HStack embedded in a ForEach in SwiftUI?如何在 SwiftUI 中嵌入 ForEach 的 HStack 中设置相对宽度?
【发布时间】:2020-07-20 09:42:34
【问题描述】:

我想创建一个属性列表(不使用列表视图)。每个属性都是一个 HStack,其中包含两个文本,名称和值。我希望名称文本始终具有整个 HStack 宽度的 30%,而值文本则使用其余的水平空间。每个属性的高度取决于内容。

我尝试通过以下观点来完成它:

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 来完成我上面描述的相对宽度。我做错了什么?

【问题讨论】:

    标签: ios swift swiftui ios14


    【解决方案1】:

    这是一个可能解决方案的演示。使用 Xcode 11.4 / iOS 13.4 测试

    注意:ViewHeightKey 取自 this another my solution

    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: $0.frame(in: .local).size.height) })
            }
            .onPreferenceChange(ViewHeightKey.self) { self.fitHeight = $0 }
            .frame(height: fitHeight)
        }
    }
    

    【讨论】:

    • 谢谢!这解决了问题!我还必须在 Text(self.attribute.name) 中添加 .fixedSize(horizontal: false, vertical: true),因为我还想垂直调整名称内容的大小。
    猜你喜欢
    • 2021-07-01
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    • 2013-08-30
    • 2021-06-16
    • 2021-06-07
    相关资源
    最近更新 更多