我正在尝试创建一个可滚动的项目网格。我创建了一个名为GridView
的自定义视图,该视图使用GeometryReader
将空间分为HStacks
和VStacks
中的列和行。但是由于某种原因,当放在ScrollView
中时,其大小几乎缩小为零。在屏幕快照中,您看到GridView
(带红色)及其父级VStack
(带绿色)已缩小。网格内部的 项仍然可见,显示在其区域的外部,但是不能正确滚动。
为什么GridView
不是容纳其项目所需的大小?如果可以,我认为该用户界面将正确滚动。
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("")
}
}
}
}
}
}
}
}
}
答案 0 :(得分:1)
GeometryReader是一个容器视图,根据其自身大小和坐标空间定义其内容。返回其灵活的首选大小 父级布局。
在
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.5))
}.background(Color.green.opacity(0.2))
}.background(Color.blue.opacity(0.2))
}
}
GridView的高度是多少? 嗯...行数乘以网格单元格的高度,也就是GridView的高度除以行数...
等式没有解:-)
是的,我将网格单元的高度定义为GridView的宽度除以列数,但是SwiftUI并不那么聪明。
您必须计算GridView的高度。我将行数固定为4以简化它...
struct ContentView: View {
var body: some View {
GeometryReader { g in
ScrollView {
VStack {
Text("Section 1")
GridView(columns: 2, items: [1, 3, 5, 7, 9, 11, 13, 15]) { num in
Text("Item \(num)")
}.frame(height: g.size.width / 2 * CGFloat(4))
.background(Color.red.opacity(0.5))
}.background(Color.green.opacity(0.2))
}.background(Color.blue.opacity(0.2))
}
}
}
最好从GridView.body中删除几何读取器和网格单元格框架,并在内容视图中设置单元格的大小。
struct ContentView: View {
var body: some View {
GeometryReader { g in
ScrollView {
VStack {
Text("Section 1")
GridView(columns: 2, items: [1, 3, 5, 7, 9, 11, 13, 15]) { num in
Text("Item \(num)").frame(width: g.size.width / 2, height: g.size .width / 2)
}
.background(Color.red.opacity(0.5))
}.background(Color.green.opacity(0.2))
}.background(Color.blue.opacity(0.2))
}
}
}
如您所见,无需定义GridView的高度,现在方程式已解决。