我试图确定哪个GridItem
将有效地位于位置x:0,y:0。为了实现这一点,我简单地尝试使用preferenceKey
和GeometryReader
。我将.overlay
添加到我的GridItems中,并在gridItemIndex 0处的GridItem
上添加GeometryReader
围绕Color.clear
。我的预期逻辑是跟踪GridItem
的Y位置。然后通过将Y偏移除以每个GridItem
的高度,我将获得当前位于顶部的项目。
我已经做到了这一点。一旦索引“gridItemIndex”位置0处的GridItem超过某个偏移量,它就不再被读取,y位置停留在0.0。我的假设是由于视图被重用?
目前我没有得到40以上的阅读,但我需要得到,直到底部的LazyVGrid出现。
这是我的代码
struct DetectScrollPosition: View {
let gridRowLayout = Array(repeating: GridItem(spacing: 0), count: 7)
@State private var scrollPosition: Int = 0
var body: some View {
NavigationView {
ScrollView (.vertical){
LazyVGrid(columns: gridRowLayout, spacing: 0){
ForEach(0..<1092, id: \.self) { gridItemIndex in
Text("\(abs(gridItemIndex / 7))")
.overlay {
if gridItemIndex == 0 {
GeometryReader { geometryProxy in
Color.clear
.updateViewsYPosition(geometryProxy)
}
}
}
}
}
.onPreferenceChange(ScrollOffsetPreferenceKey.self) { value in
self.scrollPosition = abs(Int(value))
}
}
.coordinateSpace(.named("scroll"))
.navigationTitle("The Top Row is: \(scrollPosition)")
.navigationBarTitleDisplayMode(.inline)
}
}
}
struct ScrollOffsetPreferenceKey: PreferenceKey {
static var defaultValue: CGFloat = 0
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
}
}
extension View {
func updateViewsYPosition(_ geometryProxy: GeometryProxy) -> some View {
let offset = geometryProxy.frame(in: .named("scroll")).origin.y / geometryProxy.frame(in: .named("scroll")).height
return self.preference(key: ScrollOffsetPreferenceKey.self, value: offset)
}
}
字符串
抱歉,GIF图片
2条答案
按热度按时间hmmo2u0o1#
实际上,视图正在被重用。您应该添加一个视图,为网格的每一行设置首选项。
字符串
现在我们需要在preference键中实现
reduce
方法,因为会有多个兄弟视图都设置了自己的首选项。其思想是,在减少所有内容之后,最终结果将指示左上角的视图。因此,我们需要同时存储视图的帧(用于缩小)和视图的索引(以便我们可以更新
scrollPosition
)。我们将使用如下类型的首选项键:型
这就是为什么我们还要在
gridItemIndex
中传递到overlay
中的updateViewsYPosition
。“实际的首选项键将按如下方式实现:
型
实现
reduce
后,首选项始终是y位置最接近0的视图。您可以根据需要更改此条件。在
updateViewsYPosition
中,您应该会取得scrollView
坐标空间中的框架。型
完整代码:
型
kse8i1jr2#
您只是检测第一个网格项的位置,所以我预计一旦它被滚动到视线之外一定距离,
LazyVGrid
就会丢弃它。我建议在每一行的第一个单元格后面放置一个“探测器”。此外,它可以使用
.onChange
来完成,而不是使用专用的首选项键。像这样:字符串
其他代码没有变化,只是不再需要
ScrollOffsetPreferenceKey
和视图扩展updateViewsYPosition
。