如何检测 SwiftUI 列表中的向上、向下、顶部和底部滚动 [英] How to detect scroll up, scroll down, top and bottom in SwiftUI List

查看:37
本文介绍了如何检测 SwiftUI 列表中的向上、向下、顶部和底部滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个列表,我想在列表向上滚动时隐藏工具栏和标签栏.

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

 .gesture(拖动手势().onChanged { 值输入如果 value.translation.height >0 {打印(向下滚动")} 别的 {打印(向上滚动")}}.onEnded{ 值在打印(结束")})

这会间歇性地工作,因为只有大约 80% 的时间,它似乎只有在我缓慢地滚动或将手指直接放在屏幕上然后滚动时才会检测到滚动.否则什么都没有.此外,onEnded 永远不会在这里触发.

我也试过这个:

 .gesture(DragGesture(最小距离:0,坐标空间:.local).onChanged { 值输入打印(值.translation.height)如果 value.translation.height >0 {打印(向下滚动")} 别的 {打印(向上滚动")}}.onEnded{ 值在打印(结束")打印(值.location.y)})

这捕获了我所有的滚动,这很棒.onEnded 也会触发,但问题是我的 List 实际上没有滚动.

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

解决方案

如果您只想在 SwiftUI 中执行此操作,您可以在 ScrollView 中创建一个 GeometryReader 来检测偏移更改,如下所示:https://fivestars.blog/swiftui/scrollview-offset.html

如果您不介意使用 Introspect,您可以按照此答案中的描述进行操作:https://stackoverflow.com/a/65467199/3393964


<块引用>

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

结构体示例:查看{@State var isDraggingPublisher = Just(false).eraseToAnyPublisher()@State var offsetPublisher = Just(.zero).eraseToAnyPublisher()var主体:一些视图{....introspectScrollView {self.isDraggingPublisher = $0.publisher(for: \.isDragging).eraseToAnyPublisher()self.offsetPublisher = $0.publisher(for: \.contentOffset).eraseToAnyPublisher()}.onReceive(isDraggingPublisher) {//用 isDragging 改变做一些事情}.onReceive(offsetPublisher) {//做一些改变偏移量的事情}...}

<块引用>

如果你想看一个例子;我使用这种方法在我的包 ScrollViewProxy 中获取偏移发布者.

I have a List and I would like to hide a toolbar and tab bar when the List scrolls up.

I've tried to detect movements using the following:

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

This works intermittently, as in only around 80% of the time, it only seems to detect scrolls when I do it slowly or when I place my finger down straight onto the screen and then scroll. Otherwise nothing. Also, onEnded never fires here.

I also tried this:

                    .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)
                        }
                    )

This catches all my scrolling, which is great. onEnded also fires, but the problem is my List doesn't actually scroll.

I'm at a loss here, I want to know when the user scrolls up, scrolls down, by how much, and if possible I would like to know when the user gets to the top of the list.

解决方案

If you want to do this SwiftUI only you can make a GeometryReader inside the ScrollView to detect offset change like shown here: https://fivestars.blog/swiftui/scrollview-offset.html

If you don't mind using Introspect you can do it like described in this answer: https://stackoverflow.com/a/65467199/3393964


You can use Introspect to get the UIScrollView, then from that get the publisher for UIScrollView.contentOffset and UIScrollView.isDragging to get updates on those values which you can use to manipulate your SwiftUI views.


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
        }
        ...        
}

If you want to look at an example; I use this method to get the offset publisher in my package ScrollViewProxy.

这篇关于如何检测 SwiftUI 列表中的向上、向下、顶部和底部滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆