ios 在寻找一个UIScrollView滚动的方向是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2543670/
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 17:05:22  来源:igfitidea点击:

Finding the direction of scrolling in a UIScrollView?

iphoneioscocoa-touchuiscrollview

提问by Alex1987

I have a UIScrollViewwith only horizontal scrolling allowed, and I would like to know which direction (left, right) the user scrolls. What I did was to subclass the UIScrollViewand override the touchesMovedmethod:

我有一个UIScrollView只允许水平滚动,我想知道用户滚动的方向(左,右)。我所做的是子类化UIScrollView并覆盖该touchesMoved方法:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];

    UITouch *touch = [touches anyObject];
    float now = [touch locationInView:self].x;
    float before = [touch previousLocationInView:self].x;
    NSLog(@"%f %f", before, now);
    if (now > before){
        right = NO;
        NSLog(@"LEFT");
    }
    else{
        right = YES;
        NSLog(@"RIGHT");

    }

}

But this method sometimes doesn't get called at all when I move. What do you think?

但是当我移动时,有时根本不会调用此方法。你怎么认为?

回答by memmons

Determining the direction is fairly straightforward, but keep in mind that the direction can change several times over the course of a gesture. For example, if you have a scroll view with paging turned on and the user swipes to go to the next page, the initial direction could be rightward, but if you have bounce turned on, it will briefly be going in no direction at all and then briefly be going leftward.

确定方向相当简单,但请记住,在一个手势的过程中,方向可能会发生多次变化。例如,如果您有一个滚动视图并打开了分页,并且用户滑动以转到下一页,则初始方向可能是向右,但是如果您打开了弹跳,它将暂时没有方向,并且然后短暂地向左走。

To determine the direction, you'll need to use the UIScrollView scrollViewDidScrolldelegate. In this sample, I created a variable named lastContentOffsetwhich I use to compare the current content offset with the previous one. If it's greater, then the scrollView is scrolling right. If it's less then the scrollView is scrolling left:

要确定方向,您需要使用UIScrollView scrollViewDidScroll委托。在此示例中,我创建了一个名为的变量lastContentOffset,用于将当前内容偏移量与前一个进行比较。如果它更大,则 scrollView 向右滚动。如果小于则 scrollView 向左滚动:

// somewhere in the private class extension
@property (nonatomic, assign) CGFloat lastContentOffset;

// somewhere in the class implementation
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

    ScrollDirection scrollDirection;

    if (self.lastContentOffset > scrollView.contentOffset.x) {
        scrollDirection = ScrollDirectionRight;
    } else if (self.lastContentOffset < scrollView.contentOffset.x) {
        scrollDirection = ScrollDirectionLeft;
    }

    self.lastContentOffset = scrollView.contentOffset.x;

    // do whatever you need to with scrollDirection here.    
}

I'm using the following enum to define direction. Setting the first value to ScrollDirectionNone has the added benefit of making that direction the default when initializing variables:

我使用以下枚举来定义方向。将第一个值设置为 ScrollDirectionNone 具有在初始化变量时将该方向设为默认值的额外好处:

typedef NS_ENUM(NSInteger, ScrollDirection) {
    ScrollDirectionNone,
    ScrollDirectionRight,
    ScrollDirectionLeft,
    ScrollDirectionUp,
    ScrollDirectionDown,
    ScrollDirectionCrazy,
};

回答by followben

...I would like to know which direction (left, right) the user scrolls.

...我想知道用户滚动的方向(左,右)。

In that case, on iOS 5 and above, use the UIScrollViewDelegateto determine the direction of the user's pan gesture:

在这种情况下,在 iOS 5 及更高版本上,使用UIScrollViewDelegate来确定用户平移手势的方向:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{ 
    if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].x > 0) {
        // handle dragging to the right
    } else {
        // handle dragging to the left
    }
}

回答by Justin Tanner

Using scrollViewDidScroll:is a good way to find the current direction.

使用scrollViewDidScroll:是找到当前方向的好方法。

If you want to know the direction afterthe user has finished scrolling, use the following:

如果您想知道用户完成滚动的方向,请使用以下命令:

@property (nonatomic) CGFloat lastContentOffset;

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {

    self.lastContentOffset = scrollView.contentOffset.x;
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {

    if (self.lastContentOffset < scrollView.contentOffset.x) {
        // moved right
    } else if (self.lastContentOffset > scrollView.contentOffset.x) {
        // moved left
    } else {
        // didn't move
    }
}

回答by rounak

No need to add an extra variable to keep track of this. Just use the UIScrollView's panGestureRecognizerproperty like this. Unfortunately, this works only if the velocity isn't 0:

无需添加额外的变量来跟踪这一点。只需像这样使用UIScrollView'spanGestureRecognizer属性。不幸的是,这仅在速度不为 0 时才有效:

CGFloat yVelocity = [scrollView.panGestureRecognizer velocityInView:scrollView].y;
if (yVelocity < 0) {
    NSLog(@"Up");
} else if (yVelocity > 0) {
    NSLog(@"Down");
} else {
    NSLog(@"Can't determine direction as velocity is 0");
}

You can use a combination of x and y components to detect up, down, left and right.

您可以使用 x 和 y 分量的组合来检测向上、向下、向左和向右。

回答by davidrelgr

The solution

解决方案

func scrollViewDidScroll(scrollView: UIScrollView) {
     if(scrollView.panGestureRecognizer.translationInView(scrollView.superview).y > 0)
     {
         print("up")
     }
    else
    {
         print("down")
    } 
}

回答by Alessandro Ornano

Swift 4:

斯威夫特 4:

For the horizontal scrolling you can simply do :

对于水平滚动,你可以简单地做:

if scrollView.panGestureRecognizer.translation(in: scrollView.superview).x > 0 {
   print("left")
} else {
   print("right")
}

For vertical scrolling change .xwith .y

对于垂直滚动变化.x.y

回答by Esqarrouth

In iOS8 Swift I used this method:

在 iOS8 Swift 中我使用了这个方法:

override func scrollViewDidScroll(scrollView: UIScrollView){

    var frame: CGRect = self.photoButton.frame
    var currentLocation = scrollView.contentOffset.y

    if frame.origin.y > currentLocation{
        println("Going up!")
    }else if frame.origin.y < currentLocation{
        println("Going down!")
    }

    frame.origin.y = scrollView.contentOffset.y + scrollHeight
    photoButton.frame = frame
    view.bringSubviewToFront(photoButton)

}

I have a dynamic view which changes locations as the user scrolls so the view can seem like it stayed in the same place on the screen. I am also tracking when user is going up or down.

我有一个动态视图,它会随着用户滚动而改变位置,因此视图看起来好像停留在屏幕上的同一位置。我也在跟踪用户何时上升或下降。

Here is also an alternative way:

这也是另一种方式:

func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    if targetContentOffset.memory.y < scrollView.contentOffset.y {
        println("Going up!")
    } else {
        println("Going down!")
    }
}

回答by Javier Calatrava Llavería

This is what it worked for me (in Objective-C):

这对我有用(在Objective-C中):

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView{

        NSString *direction = ([scrollView.panGestureRecognizer translationInView:scrollView.superview].y >0)?@"up":@"down";
        NSLog(@"%@",direction);
    }

回答by Oded Regev

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {

    CGPoint targetPoint = *targetContentOffset;
    CGPoint currentPoint = scrollView.contentOffset;

    if (targetPoint.y > currentPoint.y) {
        NSLog(@"up");
    }
    else {
        NSLog(@"down");
    }
}

回答by xu huanze

Alternatively, it is possible to observe key path "contentOffset". This is useful when it's not possible for you to set/change the delegate of the scroll view.

或者,可以观察关键路径“contentOffset”。当您无法设置/更改滚动视图的委托时,这很有用。

[yourScrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

After adding the observer, you could now:

添加观察者后,您现在可以:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    CGFloat newOffset = [[change objectForKey:@"new"] CGPointValue].y;
    CGFloat oldOffset = [[change objectForKey:@"old"] CGPointValue].y;
    CGFloat diff = newOffset - oldOffset;
    if (diff < 0 ) { //scrolling down
        // do something
    }
}

Do remember to remove the observer when needed. e.g. you could add the observer in viewWillAppearand remove it in viewWillDisappear

请记住在需要时移除观察者。例如,你可以在添加观察者viewWillAppear中,并删除它viewWillDisappear