如何将VStack拆分为两个子视图,第二个子视图的高度比第一个子视图的高度高两倍

时间:2019-07-04 19:14:11

标签: swiftui

我刚开始使用SwiftUI,似乎VStack和HStack与Web中的flex box非常相似。在网络上,使用flex可以很容易地将两个子视图拆分为高度权重

<div id="parent" style="display: flex; flex-direction: column; height: 300px">
  <div id="subA" style="flex: 1; background-color: red">Subview A</div>
  <div id="subB" style="flex: 2; background-color: yellow">Subview B</div>
</div>

enter image description here

我想知道swiftUI上是否也可以。

VStack {
    VStack {
        Text("Subview A")
    } // Subview A with height 100
        .background(Color.red)
    VStack {
        Text("Subview B")
    } // Subview B with height 200
        .background(Color.yellow)
}
    .frame(height: 300, alignment: .center)

请帮助我如何实现该目标。

1 个答案:

答案 0 :(得分:3)

重要编辑#2

不确定为什么我仍然收到不赞成使用的东西的投票,但是由于@kontiki的answer and code,这很容易实现,而不是使用此不推荐使用的方法:< / p>

声明此:

@State private var rect: CGRect = CGRect()

然后创建一个:

struct GeometryGetter: View {
    @Binding var rect: CGRect

    var body: some View {
        GeometryReader { geometry in
            Group { () -> ShapeView<Rectangle, Color> in
                DispatchQueue.main.async {
                    self.rect = geometry.frame(in: .global)
                }
                return Rectangle().fill(Color.clear)
            }
        }
    }
}

(对于熟悉UIKit的人,您基本上在父级中创建不可见的CALayerUIView并将其框架传递给子视图-抱歉并非100%在技术上都是准确的,但是请记住,这不是绝对不是UIKit堆栈。)

现在有了父框架,您可以将其用作百分比(或“相对”)的基础。在这个问题中,另一个VStack中有一个嵌套的Text,而您希望较低的relativeHeight是顶部的垂直大小的两倍。对于此答案,请将您的`ContentView调整为此:

struct ContentView:查看{     @State私有var rect:CGRect = CGRect()     var主体:某些视图{         VStack(间距:0){             RedView()。background(Color.red)                 .frame(高度:矩形高度* 0.25)             YellowView()         }         .background(GeometryGetter(rect:$ rect))     } }

重要编辑:

从beta 4开始,该方法已弃用。 relativeWidthhave all been deprecated. Use,relativeSize instead. If you want *relatve* sizing based on a框架's parent, use视图relativeHeight改为使用GeometryReader`。 (请参见this question。)


这就是您想要的。请记住,没有修饰符,所有内容都会居中。另外,VSTack似乎(至少在某些情况下)不是很直观。关键是要记住,在frame中,父级是屏幕的50%,所以50%的50%实际上是25%。

或者,您可以指定struct RedView: View { var body: some View { ZStack { Color.red Text("Subview A") } } } struct YellowView: View { var body: some View { ZStack { Color.yellow Text("Subview B") } } } struct ContentView : View { var body: some View { VStack (spacing: 0) { RedView().background(Color.red).relativeHeight(0.50) YellowView() } } } 的高度(让宽度占据整个屏幕)。但是您的示例建议您无论实际屏幕大小是多少,都希望红色视图占整个屏幕的25%。

<Route path="/section/(page)?/:page?/(sort)?/:sort?" component={Section} />

enter image description here