如何优雅地获取 ScrollView 的滚动方向

在有些场景,我们可能需要获取 UIScrollView (及其子类)的滚动方向来做不同的操作。

我们首先能想到最直观的方法是:用一个变量或属性 lastContentOffset 去保存 scrollView 上次的 content offset 值,然后在 UIScrollViewscrollViewDidScroll: delegate 方法中跟 scrollView 当前实时的 content offset 做对比来判断滚动方向,代码大致如下:

// @property (nonatomic, assign) CGFloat lastContentOffset;

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (self.lastContentOffset > scrollView.contentOffset.y) {
        // 向下滚动
    } else if (self.lastContentOffset < scrollView.contentOffset.y) {
        // 向上滚动
    }
    self.lastContentOffset = scrollView.contentOffset.y;
}

今天我们同事在阅读第三方开源代码时,看到一个更简便的方法,同样在 scrollViewDidScroll: 方法中,先获取 scrollView 的 panGestureRecognizer (拖拽/移动动作)手势,然后把手势滑动的相对偏移在当前 view 上转换成一个 point ,最后根据 point 的 x 或 y 来判断左右/上下滚动方向,代码如下:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGPoint point = [scrollView.panGestureRecognizer translationInView:self.view];
    if (point.y > 0) {
        // 向下滚动
    } else {
        // 向上滚动
    }
}

虽然这种方式看似很优雅,可以不用借助额外的变量来完成,但它存在一个问题,如下图所示,我们手指按住屏幕不放,先向上滑动一段距离(从 A -> B,向上)然后改变滑动方向再向下滑动一段距离,(从 B -> A -> C,向下):

如何优雅地获取 ScrollView 的滚动方向

但这时候通过第二种方法判断实际得到的结果是:A -> B 向上滚动,B -> A 向上滚动,A -> C 向下滚动,显然,其中 B -> A 的方向判断是错的,应该是向下。

原因在于,上述方法中拖拽手势的相对偏移 point 是根据滑动的起始点 A 来进行计算的,所在只要手势停留在起始点 A 之上,不管向上还是向下滑动,它都认为是向上滚动了。

所以这种优雅的方法只适用于 scrollView 一次手势滑动中不改变方向的情况。

参考连接: Finding the direction of scrolling in a UIScrollView?

原文 

https://kangzubin.com/scrollview-direction/

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 如何优雅地获取 ScrollView 的滚动方向

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址