SwiftUI动态设置视图相对于父视图的高度



我正在尝试创建一组这样的视图:

var body: some View {
GeometryReader { reader in
VStack {
ScrollView(.horizontal) {
HStack(alignment: .bottom) {
ForEach(0..<24) { hour in
VStack {
Rectangle()
.fill(Color.orange)
.frame(
height: model.height(hour, containerHeight: reader.size.height), alignment: .bottom)
Text("(hour)").font(.caption2)
}
}
}
}
Text("Hour of Day")
}
}
}

视图的模型由此产生高度值:

func height(_ hour: Int, containerHeight: CGFloat) -> CGFloat {
let steps = CGFloat(hourSteps[hour] ?? 0)
let cgMax = CGFloat(maxSteps)
return (steps/cgMax)*containerHeight*10
}

这是有效的,但我注意到GeometryReader的高度值发生了变化,导致一些视图与一个高度成比例,另一些视图与另一个成比例。

我不确定GeometryReader是正确的,也不确定我是否正确使用了它或SwiftUI,谢谢你的阅读。

如果没有MRE,我只能向您展示一个工作示例。有几点。首先,GeometryReader位于错误的位置。它应该在酒吧本身,因为这是需要知道可用高度的元素。第二,在创建这样的视图时,将它们分解为单独的视图。以这种方式调试视图会变得容易得多。

因此,我将制作酒吧的代码重构到自己的视图中。该视图包含GeometryReader。制作条形图时,我喜欢有一个完整的高度元素,然后使用百分比高度元素的.overlay(),在.overlay()上对齐.bottom。一旦你掌握了基本知识,你就可以把它放在你的ForEach中。显然,这个元素可以变得更可定制,但注入不同的颜色等。

struct BarGraphView: View {
var body: some View {
VStack {
ScrollView(.horizontal) {
VStack {
HStack {
ForEach(1..<25) { hour in
VStack {
BarView(percentage: CGFloat(hour)/CGFloat(24))
Text("(hour)")
.font(.caption2)
.lineLimit(1)

}
.frame(width: 50, height: 500)
}
}
Text("Hour of Day")
}
}
.padding()
}
}
}
struct BarView: View {

let percentage: CGFloat

var body: some View {
GeometryReader { reader in
Rectangle()
.fill(Color.gray) // if you make this clear, there is no background.
.frame(width: reader.size.width)
.overlay(
VStack {
Rectangle()
.fill(Color.orange)
}
.frame(height: percentage * reader.size.height),
alignment: .bottom)
}
}
}

最新更新