【问题标题】:Detect direction of UIScrollView scroll in scrollViewWillBeginDragging在 scrollViewWillBeginDragging 中检测 UIScrollView 滚动的方向
【发布时间】:2012-12-12 02:34:03
【问题描述】:

我在谷歌上做了足够多的事情,并且在发布之前我确实在 stackoverflow 中检查了这些帖子 (Finding the direction of scrolling in a UIScrollView?)。我在 iPhone 应用程序中有动态数量的照片,通过UIScrollView 显示。在任何时候,滚动视图中都只显示了 3 张照片。当我总共有 4 张照片时: 第一张照片:在偏移量 0.0 处显示 第二张照片:显示在偏移 320.0 第三张照片:显示在偏移 640.0

现在,当用户滚动到第四张照片时,滚动视图重置为 0.0 偏移量。如果用户试图滚动“超出”第 4 张照片,则滚动应仅在右侧停止(这样用户不会滚动“超出”)。但目前,用户“能够”滚动到最后一张照片之外;但是,我以编程方式检测到这一点并重置偏移量。但它看起来并不整洁,因为用户会暂时看到黑色背景。我想检测到用户已经开始在scrollViewWillBeginDragging 中“向右”滚动(记住,向“左”滚动,即到“上一张”照片是可以的),这样我就可以停止向右滚动。

我尝试了什么:

  1. 尝试使用self.scrollView.panGestureRecognizer's translationInView 不起作用,因为没有 panGestureRecognizer 实例首先返回(!), 虽然 UIScrollView API 声称如此。
  2. 虽然可以在scrollViewDidEndDecelerating 中检测到这一点 这不符合我的目的。

【问题讨论】:

    标签: iphone ios cocoa-touch


    【解决方案1】:

    检查滚动视图的panGestureRecognizer 时,我在确定scrollViewWillBeginDragging 的方向时没有问题:

    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    { 
        CGPoint translation = [scrollView.panGestureRecognizer translationInView:scrollView.superview];
    
        if(translation.y > 0)
        {
            // react to dragging down
        } else
        {
            // react to dragging up
        }
    }
    

    我发现当用户向禁止方向拖动时,在第一次拖动时取消滚动非常有用。

    【讨论】:

    • 翻译似乎总是为零(至少在 iOS7.1 中)
    • 翻译有时会为零,所以这只有“kindof”有效(iOS 8.3)
    • 改用scrollViewDidScroll
    • 如果translation > 0 - UP!
    • 注意,如果手势过于微妙,翻译可能会返回零。使用 CGPoint velocity = [scrollView.panGestureRecognizer velocityInView:scrollView.superview];反而。感谢用户 Robert 对此问题的评论:stackoverflow.com/questions/9637203/…
    【解决方案2】:

    Swift 3 解决方案

    1- 添加 UIScrollViewDelegate

    2- 添加此代码

    func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
        let actualPosition = scrollView.panGestureRecognizer.translation(in: scrollView.superview)
        if (actualPosition.y > 0){
            // Dragging down
        }else{
            // Dragging up
        }
    }
    

    【讨论】:

      【解决方案3】:

      适用于 swift 2.0+ & ios 8.0+

      func scrollViewWillBeginDecelerating(scrollView: UIScrollView) {
          let actualPosition = scrollView.panGestureRecognizer.translationInView(scrollView.superview)
          if (actualPosition.y > 0){
              // Dragging down 
          }else{
              // Dragging up
          }
      }
      

      【讨论】:

        【解决方案4】:

        谢谢你,克里斯。最后,这对我有用:

        - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
            // Detect the scroll direction
            if (lastContentOffset < (int)scrollView.contentOffset.x) {
            ...
            }
        }
        

        【讨论】:

        • 能否详细说明 lastContentOffset
        • @Daniel 您需要保存“最后一个内容偏移量”,即上次调用此方法时的上一个 contentOffset。我不知道Jean为什么忘记了。只需在顶部添加 lastContentOffset 作为静态变量,然后将其设置在方法的末尾即可。
        【解决方案5】:

        这是我使用的,它至少在 iOS 6.0 上运行良好:

        - (void)scrollViewDidScroll:(UIScrollView*)scrollView
        {
           CGPoint translation = [scrollView.panGestureRecognizer translationInView:scrollView];
        
           // Detect direction by accessing x or y of translation
        }
        

        为您保存lastContentOffset 的实例变量...

        【讨论】:

          【解决方案6】:

          看看scrollViewWillEndDragging:withVelocity:targetContentOffset:。 您可以使用该方法进行任何检查,看看它是否会去不应该的地方,然后在该方法中您可以设置一个新的targetContentOffset。

          每the documentation:

          当滚动视图的 pagingEnabled 属性值为 YES 时,不会调用此方法。您的应用程序可以更改 targetContentOffset 参数的值,以调整滚动视图完成其滚动动画的位置。

          【讨论】:

            【解决方案7】:

            在 iOS 7+ 中基于滚动视图的平移识别器的翻译检测滚动方向似乎存在问题。就我的目的而言,这似乎可以无缝地工作

            func scrollViewDidScroll(scrollView: UIScrollView) {
                if !scrollDirectionDetermined {
                    let translation = scrollView.panGestureRecognizer.translationInView(self.view)
                    if translation.y > 0 {
                        println("UP")
                        scrollDirectionDetermined = true
                    }
                    else if translation.y < 0 {
                        println("DOWN")
                        scrollDirectionDetermined = true
                    }
                }
            }
            
            func scrollViewWillBeginDragging(scrollView: UIScrollView) {
                scrollDirectionDetermined = false
            }
            
            func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
                scrollDirectionDetermined = false
            }
            

            【讨论】:

              【解决方案8】:

              scrollView.panGestureRecognizer translationInView:scrollView 在 iOS 7 中的scrollViewWillBeginDragging 中没有报告任何有用的信息。

              这样做:

              在@interface

              BOOL scrollDirectionDetermined;
              

              和:

              - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
                  if (!scrollDirectionDetermined) {
                      if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].x > 0) {
                          //scrolling rightwards
                      } else {
                           //scrolling leftwards
                     }
                  scrollDirectionDetermined = YES;
                  }
              }
              

              和:

              - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
                  scrollDirectionDetermined = NO;
              }
              

              【讨论】:

                【解决方案9】:

                根据@Oscar 的回答,您可以做类似的事情

                scrollView.bounces = actualPosition.y &lt; 0 如果您希望滚动视图在滚动到底部而不是在滚动到顶部时反弹

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2012-03-27
                  • 2011-04-17
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-07-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多