我正在尝试创建一个可滚动的项目网格。我创建了一个名为的自定义视图GridView
,用于GeometryReader
将空间划分为 和 中的列和HStacks
行VStacks
。但由于某种原因,它的大小在ScrollView
. 在屏幕截图中,您看到GridView
(红色)和它的父VStack
级(绿色)缩小了。网格内的项目仍然可见,呈现在其区域之外,但无法正确滚动。
为什么GridView
不是包含其项目所需的大小?如果是这样,我认为这个 UI 会正确滚动。
struct ContentView: View {
var body: some View {
ScrollView {
VStack {
Text("Section 1")
GridView(columns: 2, items: [1, 3, 5, 7, 9, 11, 13, 15]) { num in
Text("Item \(num)")
}
.background(Color.red.opacity(0.2))
}.background(Color.green.opacity(0.2))
}.background(Color.blue.opacity(0.2))
}
}
struct GridView<Content>: View where Content: View {
var columns: Int
let items: [Int]
let content: (Int) -> Content
init(columns: Int, items: [Int], @ViewBuilder content: @escaping (Int) -> Content) {
self.columns = columns
self.items = items
self.content = content
}
var rowCount: Int {
let (q, r) = items.count.quotientAndRemainder(dividingBy: columns)
return q + (r == 0 ? 0 : 1)
}
func elementFor(_ r: Int, _ c: Int) -> Int? {
let i = r * columns + c
if i >= items.count { return nil }
return items[i]
}
var body: some View {
GeometryReader { geo in
VStack {
ForEach(0..<self.rowCount) { ri in
HStack {
ForEach(0..<self.columns) { ci in
Group {
if self.elementFor(ri, ci) != nil {
self.content(self.elementFor(ri, ci)!)
.frame(width: geo.size.width / CGFloat(self.columns),
height: geo.size.width / CGFloat(self.columns))
} else {
Text("")
}
}
}
}
}
}
}
}
}