如何在SwiftUI列表中检测向上、向下、顶部和底部滚动



我有一个列表,当列表向上滚动时,我想隐藏工具栏和选项卡栏。

我尝试使用以下方法检测移动:

.gesture(
DragGesture()
.onChanged { value in
if value.translation.height > 0 {
print("Scroll down")
} else {
print("Scroll up")
}
}
.onEnded{ value in
print("ended")
}
)

这是间歇性的,因为只有在大约80%的时间里,它似乎只有在我慢慢操作或将手指直接放在屏幕上然后滚动时才能检测到滚动。否则什么都没有。此外,onEnded从未在此处点火。

我也试过这个:

.gesture(
DragGesture(minimumDistance: 0, coordinateSpace: .local)
.onChanged { value in

print(value.translation.height)
if value.translation.height > 0 {
print("Scroll down")
} else {
print("Scroll up")
}
}
.onEnded{ value in
print("ended")

print(value.location.y)
}
)

这抓住了我所有的滚动,这太棒了。onEnded也会触发,但问题是我的列表实际上并没有滚动。

我在这里不知所措,我想知道用户何时向上滚动,向下滚动多少,如果可能的话,我想了解用户何时到达列表的顶部。

如果您只想执行SwiftUI,您可以在ScrollView中制作GeometryReader来检测偏移量的变化,如下所示:https://fivestars.blog/swiftui/scrollview-offset.html

如果您不介意使用Introspect,您可以按照下面的回答进行操作:https://stackoverflow.com/a/65467199/3393964


您可以使用Intrspect获取UIScrollView,然后从中获取UIScrllView.contentOffset和UIScrollView.isDraging的发布者,以获取可用于操作SwiftUI视图的值的更新。


struct Example: View {
@State var isDraggingPublisher = Just(false).eraseToAnyPublisher()
@State var offsetPublisher = Just(.zero).eraseToAnyPublisher()
var body: some View {
...
.introspectScrollView {
self.isDraggingPublisher = $0.publisher(for: .isDragging).eraseToAnyPublisher()
self.offsetPublisher = $0.publisher(for: .contentOffset).eraseToAnyPublisher()
}
.onReceive(isDraggingPublisher) { 
// do something with isDragging change
}
.onReceive(offsetPublisher) { 
// do something with offset change
}
...        
}

如果你想看看一个例子;我使用此方法在我的软件包ScrollViewProxy中获取偏移发布者。

最新更新