SwiftUI 中的比例高度(或宽度)

Proportional height (or width) in SwiftUI

我开始探索 SwiftUI,但我找不到一种方法来获得一个简单的东西:我希望 View 具有成比例的高度(基本上是其 parent 高度的百分比)。假设我有 3 个垂直堆叠的视图。我要:

我在 WWDC19 上观看了这个关于 SwiftUI 中的自定义视图的有趣视频 (https://developer.apple.com/videos/play/wwdc2019/237/) 并且我理解(如果我错了请纠正我)基本上视图本身从来没有大小,大小是其 children 的大小。因此,parent 视图询问其 children 它们有多高。他们会这样回答:“你身高的一半!”然后什么?布局系统(与我们习惯的布局系统不同)如何处理这种情况?

如果你写下面的代码:

struct ContentView : View {
    var body: some View {
        VStack(spacing: 0) {
            Rectangle()
                .fill(Color.red)
            Rectangle()
                .fill(Color.green)
            Rectangle()
                .fill(Color.yellow)
        }
    }
}

SwiftUI 布局系统将每个视图的大小设置为 1/3 高,根据我在上面发布的视频,这是正确的。 您可以这样将矩形包裹在一个框架中:

struct ContentView : View {
    var body: some View {
        VStack(spacing: 0) {
            Rectangle()
                .fill(Color.red)
                .frame(height: 200)
            Rectangle()
                .fill(Color.green)
                .frame(height: 400)
            Rectangle()
                .fill(Color.yellow)
        }
    }
}

这样,布局系统将第一个矩形调整为 200 高,第二个调整为 400 高,第三个调整为适合所有左侧 space。再一次,这很好。 您不能(通过这种方式)指定比例高度。

你可以利用GeometryReader。将 reader 包裹在所有其他视图周围并使用其闭包值 metrics 来计算高度:

let propHeight = metrics.size.height * 0.43

使用方法如下:

import SwiftUI

struct ContentView: View {
    var body: some View {
        GeometryReader { metrics in
            VStack(spacing: 0) {
                Color.red.frame(height: metrics.size.height * 0.43)
                Color.green.frame(height: metrics.size.height * 0.37)
                Color.yellow
            }
        }
    }
}

import PlaygroundSupport

PlaygroundPage.current.liveView = UIHostingController(rootView: ContentView())