如何在VStack中限制GeometryReader的大小

时间:2020-05-06 10:12:51

标签: swiftui vstack geometryreader

我想阻止GeometryReader干扰我在VStack中的布局,但是我不确定什么是正确的方法。

给出一个带有标题和标题的简单图形的示例:

struct Graph: View {
  var body: some View {
    HStack(spacing: 0) {
      Color.red.frame(width: 100, height: 80)
      Color.blue.frame(width: 100, height: 120)
      Color.green.frame(width: 100, height: 180)
    }
  }
}

struct GraphExample: View {
  var body: some View {
    VStack {

      Text("My graph")

      // Graph represents a custom view with a natural and non-static height
      Graph()

      Text("My graph caption")
    }
  }
}

产生此预期结果:

enter image description here

但是,如果我们更新Graph视图以使用GeometryReader在屏幕的整个宽度上均匀划分图形,则布局会发生变化。

struct Graph: View {
  var body: some View {
    GeometryReader { proxy in
      HStack(spacing: 0) {
        Color.red.frame(width: proxy.size.width / 3, height: 80)
        Color.blue.frame(width: proxy.size.width / 3, height: 120)
        Color.green.frame(width: proxy.size.width / 3, height: 180)
      }
    }
  }
}

这将使Graph视图填充VStack中的所有可用空间

enter image description here

有没有一种方法可以让Graph视图仅填充其自然高度,而在仍使用GeometryReader时不消耗所有可用高度。

请记住,Graph可能是此处不知道确切大小的任何视图,因此无法设置静态大小。也就是说,如果没有GeometryReaderGraph只能占用VStack中所需的垂直空间。

1 个答案:

答案 0 :(得分:0)

这是可能的解决方案。使用Xcode 11.4 / iOS 13.4进行了测试

enter image description here

struct Graph: View {
  @State private var width = UIScreen.main.bounds.width // just initial constant
  var body: some View {
      HStack(spacing: 0) {
        Color.red.frame(width: width / 3, height: 80)
        Color.blue.frame(width: width / 3, height: 120)
        Color.green.frame(width: width / 3, height: 180)
      }.background(GeometryReader { gp -> Color in
        let frame = gp.frame(in: .local)
        DispatchQueue.main.async {
            self.width = frame.size.width // << dynamic, on layout !!
        }
        return Color.clear
      })
  }
}