UIScrollView 在分页时确定 scrollViewDidEndDragging 上的滚动方向

Posted

技术标签:

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

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

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

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

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

(我在 iPad 上使用 ios4.3)

【问题讨论】:

【参考方案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 中滚动然后在开始向右移动时停止,与实际位置相比,它会给出错误的结果。测试接口时总是做“疯狂的猴子测试”;)

以上是关于UIScrollView 在分页时确定 scrollViewDidEndDragging 上的滚动方向的主要内容,如果未能解决你的问题,请参考以下文章

Gridpanel在分页时丢失了过滤器

NetSuite:FreeMarker/BFO 图像在分页时被切断

如何使用猫鼬和EJS实现分页并在分页时保留搜索查询?

UITextView 在分页 UIScrollView 内滚动不起作用

iOS:无法在分页的 UIScrollView 中的 UITableView 之间滚动

今天发现一个很奇怪的问题,在使用easyui datagrid时,行号在分页时不起作用。