更新 #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. Useframeinstead. If you want *relatve* sizing based on aView'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()
}
}
}