如何将 VStack 拆分为两个子视图,第二个子视图的高度是第一个子视图的两倍?
Posted
技术标签:
【中文标题】如何将 VStack 拆分为两个子视图,第二个子视图的高度是第一个子视图的两倍?【英文标题】:How can I split VStack to two sub view with double height of second sub view than first sub view? 【发布时间】:2019-07-04 19:14:11 【问题描述】:我刚开始使用 SwiftUI,似乎 VStack 和 HStack 与 web 中的 flex box 非常相似。在 web 上,很容易使用 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>
我想知道在 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】:更新 #2:
感谢来自@kontiki 的answer and code,以下是使用此已弃用 方法的简单方法:
声明:
@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
的人,您基本上在父视图中创建一个不可见的 CALayer
或 UIView
并将其框架传递给子视图 - 抱歉在技术上不是 100%准确,但请记住,这不是UIKit
堆栈。)
现在您有了父框架,您可以将它用作它的百分比(或“相对”)的基础。在这个问题中,有一个嵌套的 VStack
在另一个内部,您希望较低的 Text
是顶部的垂直大小的两倍。在这个答案的情况下,将您的 `ContentView 调整为:
struct ContentView : View
@State private var rect: CGRect = CGRect()
var body: some View
VStack (spacing: 0)
RedView().background(Color.red)
.frame(height: rect.height * 0.25)
YellowView()
.background(GeometryGetter(rect: $rect))
更新 #1:
从 beta 4 开始,此方法已弃用。 改为 relativeHeight
、relativeWidth
、relativeSizehave all been deprecated. Use
frameinstead. If you want *relatve* sizing based on a
View's parent, use
GeometryReader`。 (见this question。)
原帖:
这就是你想要的。请记住,没有修饰符,一切都是居中的。此外,relativeHeight
似乎(至少对某些人来说)不是很直观。关键是要记住,在VSTack
中,父级占屏幕的 50%,因此 50% 的 50% 实际上是 25%。
或者,您可以指定frame
高度(让宽度占据整个屏幕)。但是您的示例表明,无论实际屏幕尺寸是多少,您都希望红色视图占整个屏幕的 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()
【讨论】:
那么你的意思是用 VStack 作为子视图是不可能的吗? 我不确定你的意思。我的ContentView
是一个`VStack`。
啊,没关系。当然,这是一个“基地”。 RedView
和 YellowView
没有理由不能包含 VStack
而不是普通的 Text
。在运行时SwiftUI will compress them into a single
View`。 真正的部分是了解将修饰符放置在何处(以及以什么顺序)。
我的意思是您的RedView
和YellowView
基于ZStack,但有时我需要使用VStack
作为子视图,其中包含多个文本和按钮。上面只有一个Text
的例子只是例子
我还尝试将relativeHeight(0.50)
应用于VStack
,但结果出乎意料,正如您提到的50% of 50%
。这是苹果还需要解决的问题吗?以上是关于如何将 VStack 拆分为两个子视图,第二个子视图的高度是第一个子视图的两倍?的主要内容,如果未能解决你的问题,请参考以下文章
如何将两个不同的ListAPIView转换为单个ModelViewSet