如何在带有HStack的SwiftUI视图中使所有视图具有相同的高度?

时间:2020-10-06 18:30:24

标签: swift swiftui

我想要一个简单的图形,其中每个数据点都有一个可变高度的彩色矩形。 彩色矩形下方的空白应扩展,以便底部的数字与顶部的数字排成一行。

这是我的观点:

enter image description here

因此,我希望采用一种惯用的解决方案,使最下面的数字与59对齐。欢迎向我指出正确方向的任何建议。谢谢。

这是我到目前为止所拥有的:

struct DemoView: View {
    var dataSource = [1, 0, 34, 12, 59, 44]
    /// Provide a Dynamic Height Based on the Tallest View in the Row
    @State private var height: CGFloat = .zero // < calculable height
    /// The main view is a row of variable height views
    var body: some View {
        HStack(alignment: .top) {
            Spacer()
            /// i want these to all be the same height
            ForEach(0 ..< 6) { index in
                VStack {
                    Text("\(index)")
               Rectangle()
                   .fill(Color.orange)
                   .frame(width: 20, height: CGFloat(self.dataSource[index]))
                Text("\(dataSource[index])")
                }
           }
            Spacer()
        }
        .alignmentGuide(.top, computeValue: { d in
                DispatchQueue.main.async {
                    self.height = max(d.height, self.height)
                }
                return d[.top]
            })
    }
}

struct Demo_Preview: PreviewProvider {
    static var previews: some View {
        DemoView()
    }
}

编辑以显示最终结果:

我做了Asperi建议的更改,将.top的对齐方式更改为.bottom,并得到了一个非常漂亮的简单图表:

enter image description here

1 个答案:

答案 0 :(得分:3)

这是可能的(似乎是最简单的)方法。经过Xcode 12 / iOS 14的测试

demo

struct DemoView: View {
    var dataSource = [1, 0, 34, 12, 59, 44]

    var body: some View {
        HStack(alignment: .top) {
            Spacer()
            /// i want these to all be the same height
            ForEach(0 ..< 6) { index in
                VStack {
                    Text("\(index)")
                    Color.clear
                        .frame(width: 20, height: CGFloat(dataSource.max() ?? 0))
                        .overlay(
                            Color.orange
                                .frame(height: CGFloat(self.dataSource[index]))
                        , alignment: .top)
                    Text("\(dataSource[index])")
                }
            }
            Spacer()
        }
    }
}