我正在建立一个带有卡片的网格,这些卡片的顶部是图像视图,底部是一些文本。这是该组件的快速UI代码:
struct Main: View {
var body: some View {
ScrollView {
LazyVGrid(columns: .init(repeating: .init(.flexible()), count: 2)) {
ForEach(0..<6) { _ in
ZStack {
Rectangle()
.foregroundColor(Color(UIColor.random))
VStack {
Rectangle()
.frame(minHeight: 72)
Text(ipsum)
.fixedSize(horizontal: false, vertical: true)
.padding()
}
}.clipShape(RoundedRectangle(cornerRadius: 10))
}
}.padding()
}.frame(width: 400, height: 600)
}
}
此组件输出以下布局:
这看起来不错,但我想在Card组件中添加一个Geometry读取器,以便根据包围的网格列的宽度缩放顶部的图像视图。据我所知,该代码应如下所示:
struct Main: View {
var body: some View {
ScrollView {
LazyVGrid(columns: .init(repeating: .init(.flexible()), count: 2)) {
ForEach(0..<6) { _ in
ZStack {
Rectangle()
.foregroundColor(Color(UIColor.random))
VStack {
GeometryReader { geometry in
Rectangle()
.frame(minHeight: 72)
Text(ipsum)
.fixedSize(horizontal: false, vertical: true)
.padding()
}
}
}.clipShape(RoundedRectangle(cornerRadius: 10))
}
}.padding()
}.frame(width: 400, height: 600)
}
}
麻烦的是,它呈现为以下内容:
如您所见,我什至没有尝试使用GeometryReader,我只是添加了它。如果我在顶层添加几何读取器,它将正确渲染网格,但是这对我来说并没有太大用处,因为我计划将组件抽象为其他符合View的结构。此外,GeometryReader似乎在上下文上有用,并且进行一堆数学运算以将宽度值切成两半,然后再从那里进行计算(考虑到几何形状来自顶层(全宽)),这是没有意义的。
我使用几何读取器不正确吗?我的理解是,它可以在组件树中的任何位置使用,而不仅仅是在顶层使用。
感谢您的光临!
答案 0 :(得分:0)
我和你有同样的问题,但我已经解决了。这是一些关键点。
如果在 LazyVGrid
和 Foreach
中设置 GeometryReader,根据 SwiftUI 布局规则,GeometryReader 将获得建议的大小(可能只有 10 磅)。更重要的是,无论GeometryReader里面是什么子视图,它都不会影响 GeometryReader和GeometryReader的父视图的大小。
因此,您的视图显示为一条黑色长条。您可以通过设置 GeometryReader { subView }.frame(some size)
,
通常,我们需要两个 GeometryReader 来实现这一点。第一个可以获取大小并做一些计算操作,然后传递给第二个。
(因为我的原代码是中文的,你可能看不懂,所以我只能给你一个简单的结构。)
GeometryReader { firstGeo in
LazyVGrid(columns: rows) {
ForEach(dataList) { data in
GeometryReader { secondGeo in
// subview
}
.frame(width: widthYouWantSubViewGet)
}
}
}
我刚开始学习 swift 一周。我的理解可能有一些错误。欢迎您帮忙改正。