UPDATE
如果您的部署目标至少为 iOS 16、macOS 13、tvOS 16 或 watchOS 9,您可以编写自定义Layout
。例如:
import SwiftUI
struct MyLayout: Layout {
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
return proposal.replacingUnspecifiedDimensions()
}
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
precondition(subviews.count == 3)
var p = bounds.origin
let h0 = bounds.size.height * 0.43
subviews[0].place(
at: p,
proposal: .init(width: bounds.size.width, height: h0)
)
p.y += h0
let h1 = bounds.size.height * 0.37
subviews[1].place(
at: p,
proposal: .init(width: bounds.size.width, height: h1)
)
p.y += h1
subviews[2].place(
at: p,
proposal: .init(
width: bounds.size.width,
height: bounds.size.height - h0 - h1
)
)
}
}
import PlaygroundSupport
PlaygroundPage.current.setLiveView(MyLayout {
Color.pink
Color.indigo
Color.mint
}.frame(width: 50, height: 100).padding())
Result:
虽然这比下面的代码更多GeometryReader
解决方案(如下),它可以更容易调试并扩展到更复杂的布局。
ORIGINAL
您可以利用GeometryReader
。让读者围绕所有其他视图并使用其闭包值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())