如何在 SwiftUI 中嵌入 ForEach 的 HStack 中设置相对宽度?

Posted

技术标签:

【中文标题】如何在 SwiftUI 中嵌入 ForEach 的 HStack 中设置相对宽度?【英文标题】:How to set relative width in a HStack embedded in a ForEach in SwiftUI? 【发布时间】: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 来完成我上面描述的相对宽度。我做错了什么?

【问题讨论】:

【参考方案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),因为我还想垂直调整名称内容的大小。

以上是关于如何在 SwiftUI 中嵌入 ForEach 的 HStack 中设置相对宽度?的主要内容,如果未能解决你的问题,请参考以下文章

在 SwiftUI 中,如何在 LinkedList 中“Foreach”节点?

如何在 SwiftUI 中使用 Foreach 视图?

如何在 SwiftUI 的 ForEach 循环中增加状态?

如何限制 ForEach 在 SwiftUI 中显示一组项目?

如何使用 SwiftUI 在 Xcode 中消除 foreach 循环的歧义

SwiftUI:如何在 ForEach 循环中不显示“case none”