UIScrollView带有“惯性”但是分页。

时间:2013-12-18 20:20:21

标签: ios objective-c uiscrollview

我有一个横向UIScrollView,我需要将此滚动视图分页。但问题是我还需要非分页UIScrollView的“惯性”效应。我一直在谷歌搜索和堆栈溢出一段时间,没有运气。

任何想法或线索,以便我可以开始阅读如何执行此任务?

谢谢!

2 个答案:

答案 0 :(得分:3)

如果禁用了分页,滚动视图将在拖动结束时调用您的委托。使用-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);
}

答案 1 :(得分:0)

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

的Mattias

#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;
}