【发布时间】:2020-02-03 18:32:50
【问题描述】:
我正在尝试创建一个可滚动的项目网格。我创建了一个名为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("")
}
}
}
}
}
}
}
}
}
【问题讨论】:
-
我用最新的 xcode 和 iOS 测试了你的代码,它为我滚动。不可滚动是什么意思?
-
我的意思是我看不到项目13和15,因为ScrollView认为GridView只是红色区域的大小(10pt高),所以它没有滚动,因为它认为它没有没必要。屏幕上的红色区域(GridView)有多大?它应该包含项目。
-
哦,我明白了,我在更大屏幕的 iPhone 上看着它,它看起来好像在滚动。但它没有,当你的滚动视图中没有元素时,它只会滚动最低限度
-
我在使用 GeometryReader 时遇到了同样的问题。根据this article,我尝试使用
fixedSize,但我没有运气。
标签: layout swiftui geometryreader