【问题标题】:UIScrollView determine scroll direction on scrollViewDidEndDragging when pagingUIScrollView 在分页时确定 scrollViewDidEndDragging 上的滚动方向
【发布时间】:2011-10-19 23:53:34
【问题描述】:

有谁知道如何确定当用户抬起手指时滚动视图将向哪个方向移动,即当调用 scrollViewDidEndDragging 时?

具体来说,当滚动视图设置为分页时。

大多数时候,我可以在 scrollViewDidScroll 中跟踪和检查 contentOffset,但是,在某些特殊情况下,用户会快速滑动屏幕。在某些情况下,左-右-左移动将滚动到下一页,而在其他情况下,相同的模式将保留在同一页面上。

我猜它与触摸的加速度(最后几点之间的差异)有关。

(我在 iPad 上使用 iOS4.3)

【问题讨论】:

    标签: iphone uiscrollview


    【解决方案1】:

    您不使用计时器,这是非常昂贵的操作。首先锁定滚动视图的方向以仅向上/向下和向左/向右移动[我想这就是你想要的]。然后用下面的代码来判断...

    CGPoint start, end;
    
    - (void)scrollViewWillBeginDragging:(UIScrollView *)sender {
        start = self.scrollView.contentOffset;
    }
    
    - (void)scrollViewDidEndDragging:(UIScrollView *)sender willDecelerate:(BOOL)decelerate {
        end = self.scrollView.contentOffset;
    }
    
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)sender {    
        NSLog(@"%d %d",(int)start.x,(int)start.y);
        NSLog(@"%d %d",(int)end.x,(int)end.y);
    }
    

    【讨论】:

    • 如果用户向右拖动 2 厘米,然后向左拖动 1 厘米。它会给出错误的方向,不是吗?
    【解决方案2】:

    这是我的解决方案,希望对我有帮助

    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    
       CGFloat pageWidth = scrollView.frame.size.width;
    
       //Old Solution
       //Switch the indicator when more than 30% of the previous/next page is visible
       //You can vary the percentage
       //int page = floor((scrollView.contentOffset.x - pageWidth * 0.3) / pageWidth) + 1;
    
    
       //New Solution
        _pageControl.currentPage = (int)scrollView.contentOffset.x / (int)pageWidth;
    }
    

    我放弃了旧的解决方案,因为新的解决方案看起来更流畅

    【讨论】:

    • 旧的解决方案很好,很方便,总共有31个单元格,每页显示5个单元格。所以最后一页将显示从索引到 26 到 30 的单元格。(索引 30 表示它是第 31 个单元格)。在这种情况下,我要乘的因子是 1/5(因为每页有 5 个单元格)
    【解决方案3】:

    实现以下 UIScrollViewDelegate 方法。 您可以比较当前内容偏移量和目标内容偏移量,然后获取方向。

    -(void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
    
        CGPoint newOffset = CGPointMake(targetContentOffset->x, targetContentOffset->y);
    
        if (newOffset.x > scrollView.contentOffset.x) {
            NSLog(@"Scrolling direction is left");
        }else{
            NSLog(@"Scrolling direction is right");
        }
    
    }
    

    【讨论】:

    • 速度可以为0,它会在你的解决方案错误的时刻设置为“右”。
    • 这是最好的答案
    【解决方案4】:

    这是一个棘手的问题,iOS 5 有 answer,但这对你没有好处。

    也许一个 hacky 解决方法是在scrollViewDidEndDragging 完成后将NSTimer 设置为一小段时间间隔(比如 0.1 秒)。然后比较内容偏移量。

    如果您想知道滚动视图是否真的会转到下一页,也许您可​​以检查内容偏移量是否超过 1/2。您可以阅读scrollViewDidScroll: 上的内容偏移量并进行一些数学运算以确定其是否超过 1/2 方式。

    【讨论】:

    • iOS 5 的答案看起来像解决方案....除了启用分页时不调用它!我确实想到了计时器方法,但我希望有一个不那么老套的解决方案。我可能会尝试以其他方式解决它,如果不是,我会尝试使用计时器方法。谢谢
    【解决方案5】:

    除了沙林反应。 她的解决方案工作正常,但如果您使用分页并且您处于滚动内容大小的末尾,您将不得不测试我们是否真的滚动到下一个“页面”:

    CGPoint start, end;
    
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        start = scrollView.contentOffset;
    }
    
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {
        end = scrollView.contentOffset;
    }
    
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
       if (start.x > end.x && end.x>0)
       {
           NSLog(@"on the previous left page");
       }
    
       if (start.x < end.x && end.x < scrollView.contentOffset.x)
       {
           NSLog(@"on the next right page");
       }
    }
    

    【讨论】:

    • 如果用户在 zigzag 中滚动然后在开始向右移动时停止,与实际位置相比,它会给出错误的结果。测试接口时总是做“疯狂的猴子测试”;)
    猜你喜欢
    • 2013-12-13
    • 2023-04-04
    • 2012-07-01
    • 1970-01-01
    • 2017-08-24
    • 2017-08-11
    • 2013-03-17
    • 1970-01-01
    • 2011-02-02
    相关资源
    最近更新 更多