ios 在 scrollViewWillBeginDragging 中检测 UIScrollView 滚动的方向

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14042203/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:37:39  来源:igfitidea点击:

Detect direction of UIScrollView scroll in scrollViewWillBeginDragging

iphoneioscocoa-touch

提问by Jean

I did google enough, & I did check posts like these ( Finding the direction of scrolling in a UIScrollView?) in stackoverflow before posting this. I have a dynamic number of photos in an iPhone App, that am displaying through UIScrollView. At any point in time, I have only 3 photos being displayed in the scroll-view. When I have, say 4 photos, in total: 1st photo : displayed at offset 0.0 2nd photo : displayed at offset 320.0 3rd photo : displayed at offset 640.0

我在 google 上做了足够多的工作,并且在发布之前在 stackoverflow 中检查了这样的帖子(在 UIScrollView 中查找滚动方向?)。我在 iPhone 应用程序中有动态数量的照片,这些照片通过UIScrollView. 在任何时候,我只有 3 张照片显示在滚动视图中。当我总共有 4 张照片时: 第一张照片:显示在偏移 0.0 第二张照片:显示在偏移 320.0 第三张照片:显示在偏移 640.0

Now, when the user scrolls to the 4th photo, the scroll-view resets to 0.0 offset. If the user tries to scroll 'beyond' the 4th photo, scrolling should stop in the right-direction only (so that user doesn't scroll 'beyond'). But currently, the user 'is able' to scroll beyond the last photo ; however, I detect this programmatically & reset the offset. But it doesn't look neat, as the user sees the black background momentarily. I want to detect that the user has started scrolling 'right' (remember, scrolling 'left' i.e. to the 'previous' photo is okay) in scrollViewWillBeginDragging, so that I can stop any further scrolling to the right.

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

What I tried:

我试过的:

  1. Trying using self.scrollView.panGestureRecognizer's translationInViewisn't working, because there is no panGestureRecognizerinstance returned in the first place (!), though the UIScrollView API claims so.
  2. Detecting this in scrollViewDidEndDeceleratingis possible, though it'll not serve my purpose.
  1. 尝试使用self.scrollView.panGestureRecognizer's translationInView是行不通的,因为首先没有 panGestureRecognizer返回实例(!),尽管 UIScrollView API 声称如此。
  2. 检测到这一点scrollViewDidEndDecelerating是可能的,尽管它不符合我的目的。

采纳答案by Jean

Thank you, Kris. This is what worked for me, finally:

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

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

回答by Matt Wielbut

I had no issues determining direction in scrollViewWillBeginDraggingwhen checking the scroll view's panGestureRecognizer:

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

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{ 
    CGPoint translation = [scrollView.panGestureRecognizer translationInView:scrollView.superview];

    if(translation.y > 0)
    {
        // react to dragging down
    } else
    {
        // react to dragging up
    }
}

I found it very useful in canceling out of a scroll at the very first drag move when the user is dragging in a forbidden direction.

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

回答by Oscar

Swift 3 Solution

Swift 3 解决方案

1- Add UIScrollViewDelegate

1- 添加 UIScrollViewDelegate

2- Add this code

2-添加此代码

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

回答by PAC

For swift 2.0+ & ios 8.0+

对于 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
    }
}

回答by Michael Thiel

This is what I used and it works nicely at least on iOS 6.0:

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

- (void)scrollViewDidScroll:(UIScrollView*)scrollView
{
   CGPoint translation = [scrollView.panGestureRecognizer translationInView:scrollView];

   // Detect direction by accessing x or y of translation
}

Saves you the instance variable for lastContentOffset...

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

回答by Kris Gellci

Take a look at scrollViewWillEndDragging:withVelocity:targetContentOffset:. You can use that method do do any checking and see if it is going where it should not and then in the method you can set a new targetContentOffset.

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

Per the documentation:

根据文档

This method is not called when the value of the scroll view's pagingEnabled property is YES. Your application can change the value of the targetContentOffset parameter to adjust where the scrollview finishes its scrolling animation.

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

回答by wfbarksdale

There seem to be issues with detecting scroll direction based on the translation of the scrollView's pan recognizer in iOS 7+. This seems to be working pretty seamlessly for my purposes

根据 iOS 7+ 中 scrollView 的平移识别器的翻译来检测滚动方向似乎存在问题。这似乎对我的目的来说非常无缝

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
}

回答by Richard Maneuv

scrollView.panGestureRecognizer translationInView:scrollViewdoesn't report anything useful in scrollViewWillBeginDraggingin iOS 7.

scrollView.panGestureRecognizer translationInView:scrollViewscrollViewWillBeginDragging在 iOS 7中没有报告任何有用的东西。

This does:

这样做:

In the @interface

在里面 @interface

BOOL scrollDirectionDetermined;

and:

和:

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

and:

和:

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

回答by Zack Shapiro

Building off of @Oscar's answer, you can do things like

以@Oscar 的回答为基础,您可以执行以下操作

scrollView.bounces = actualPosition.y < 0if you want the scrollView to bounce when you scroll to the bottom but not when you scroll to the top

scrollView.bounces = actualPosition.y < 0如果您希望滚动到底部时滚动视图反弹,但滚动到顶部时不反弹