UIScrollView 具有“惯性”但已分页。

Posted

技术标签:

【中文标题】UIScrollView 具有“惯性”但已分页。【英文标题】:UIScrollView with "inertia" but paged. 【发布时间】:2013-12-18 20:20:21 【问题描述】:

我有一个水平的UIScrollView,我需要分页这个滚动视图。但问题是我还需要非分页UIScrollView 的“惯性”效果。我一直在谷歌搜索和***ing有一段时间了,一点运气都没有。

有什么想法或线索可以让我开始阅读有关如何执行此任务的信息吗?

谢谢!

【问题讨论】:

您希望它如何工作?如果您滑动得非常快,您是否希望它滚动一段时间,而不是停留在下一页? 确实如此,但是当它停止时,我希望它停止在一个页面中。 做这样的事情很容易,但要让它感觉正确可能需要一些努力。我认为您需要完全或部分覆盖减速曲线,使其停在您想要的位置。 【参考方案1】:

如果禁用分页,滚动视图将在拖动结束时调用您的委托。使用-scrollViewWillEndDragging:withVelocity:targetContentOffset: 方法(ios 5 及更高版本),您可以确定基于惯性的目标,并更改传入的值进行修改。例如,您的委托中的这段代码将更改目标,以便滚动视图将自动减速到其边界大小的倍数。

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                     withVelocity:(CGPoint)velocity
              targetContentOffset:(CGPoint *)targetContentOffset 
    CGSize pageSize = scrollView.bounds.size;
    targetContentOffset->x = pageSize.width *
        round(targetContentOffset->x / pageSize.width);
    targetContentOffset->y = pageSize.height *
        round(targetContentOffset->y / pageSize.height);

【讨论】:

向你表达我的感激之情的唯一方式就是说:“我爱你”。这工作得很好,我正在考虑做一些更困难的事情!谢谢!!!!【参考方案2】:

我想到了一个使用scrollViewDelegate方法的解决方案:scrollViewDidScroll。在该方法中,我仅在滚动速度小于某个值时才检查速度并应用分页,因此它将保持惯性。我不使用 UIScrollView 的正常分页,而是调用 setContentOffset 方法,以便我可以在正确的时间应用分页。代码可能看起来过于复杂,但您可以将其分成更小的方法并使其看起来更好。玩弄这两个常数,看看什么效果最好。希望它至少可以帮助您朝着正确的方向前进。

马蒂亚斯

#define SPEED_MIN = 2
#define SPEED_MAX = 10


    CGFloat prevX;
    BOOL dragging;
    NSInteger page;


- (void)scrollViewDidScroll:(UIScrollView *)scrollView

    CGFloat nextX = scrollView.contentOffset.x;
    CGFloat speedX = nextX - prevX;
    speedX = (speedX < 0 ? -speedX : speedX);
    prevX = nextX;

    if (dragging)
    
        if (speedX < SPEED_MIN && page < 0)
        
            page = [self getClosestPage:scrollView];
            [scrollView setContentOffset:CGPointMake(page * scrollView.frame.size.width, 0) animated:YES];
            [scrollView setScrollEnabled:NO];
        
        else if (scrollView.contentOffset.x == page * scrollView.frame.size.width)
        
            page = -1;
            dragging = false;
            [scrollView setScrollEnabled:YES];
        
    
    else
    
        dragging = speedX > SPEED_MAX;
    

- (NSInteger)getClosestPage:(UIScrollView *)scrollView

    CGFloat x = scrollView.contentOffset.x;
    CGFloat w = scrollView.frame.size.width;
    NSInteger nbrOfPages = scrollView.contentSize.width / w;
    for (int i = 0; i < nbrOfPages; i++) 
        CGFloat dx1 = x - i*w;
        CGFloat dx2 = (i+1)*w - x;
        if (dx1 > 0 && dx2 > 0) 
            if (dx1 >= dx2) 
                return i;
             else 
                return (i+1 < nbrOfPages ? i+1 : i);
            
        
    
    return 0;

【讨论】:

以上是关于UIScrollView 具有“惯性”但已分页。的主要内容,如果未能解决你的问题,请参考以下文章

具有不同页面宽度的 UIScrollview

具有滚动效果的页面视图控制器与启用分页的 UIScrollView

启用分页的 UISCrollview

在 UIScrollView 中延迟加载不同尺寸的图像而不分页

UIScrollView里面的UIScrollView:滚动

使用自动布局在自定义 UITableViewCell 上分页 UIScrollView