28

当您实际滚动到下一页时,我正在尝试重现启用分页的滚动视图的流畅动画。似乎是UIViewAnimationCurveEaseInOut,但我需要有一个“下一页”按钮并以编程方式触发滚动。

这是我的代码:

-(void) scrollToPage:(int)page
{
    UIScrollView *scrollView = contentView;
    CGPoint offset = CGPointMake(scrollView.bounds.size.width * page, scrollView.contentOffset.y);
    [scrollView setContentOffset:offset animated: YES];     
    [self pageControlUpdate];
}

-(void) scrollToNextPage 
{
    [self scrollToPage:(pageControl.currentPage + 1)];
}

我无法重现平滑度UIViewAnimationCurveEaseInOut,无论是使用setContentOffset还是使用scrollRectToVisible...它都会以丑陋的线性动画进入下一页

我什至尝试手动对其进行动画处理:

[UIView animateWithDuration:.5 delay:0 options:UIViewAnimationCurveEaseInOut animations:^{
    scrollView.contentOffset = offset;
} completion:^(BOOL finished) {    } ];

我哪里错了?

4

4 回答 4

21

每次制作自己的动画时,都必须将NO作为animated:参数传递:

- (void)scrollToPage:(int)page
{
    UIScrollView *scrollView = contentView;
    CGPoint offset = CGPointMake(scrollView.bounds.size.width * page, 
                                 scrollView.contentOffset.y);

    [UIView animateWithDuration:.5
                          delay:0
                        options:UIViewAnimationCurveEaseInOut
                     animations:^{
                         [scrollView setContentOffset:offset animated:NO];
                     } completion:nil];

    [self pageControlUpdate];
}
于 2012-06-14T11:15:48.950 回答
6

通过使用公共 API,我认为目前这是不可能的。假设您在动画过程中不需要用户交互,那么您最好为您UIScrollView的子视图的位置(即滚动视图的内容)设置动画,然后contentOffset在完成时调整无动画。你可以这样做:

- (void) scrollToPage:(int)page {
    UIScrollView *scrollView = contentView;
    scrollView.userInteractionEnabled = NO;
    CGPoint offset = CGPointMake(scrollView.bounds.size.width * page, scrollView.contentOffset.y);
    CGFloat delta = offset.x - scrollView.contentOffset.x;

    __block int animationCount = 0;
    for (UIView *view in scrollView.subviews) {
        [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            animationCount++;
            CGRect frame = view.frame;
            frame.origin.x -= delta;
            view.frame = frame;
        } completion:^(BOOL finished) {
            animationCount--;
            if (animationCount == 0) {
                scrollView.contentOffset = offset;
                for (UIView *view in scrollView.subviews) {
                    CGRect frame = view.frame;
                    frame.origin.x += delta;
                    view.frame = frame;
                }
                scrollView.userInteractionEnabled = YES;
            }
        }];
    }
}

我可以确认这按预期工作,我自己测试过。

于 2012-06-18T04:13:27.030 回答
4
[UIView animateWithDuration:(Animation_Duration)
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseInOut
                     animations:^{
                     [scroll setContentOffset:CGPointMake(PointX, PointY) animated:NO];
                      }
                     completion:^(BOOL finished){}];`
于 2012-11-30T13:32:06.697 回答
3

这门课绝对救了我的命:

GitHub.com 上的 MOScroll

它有

- (void)setContentOffset:(CGPoint)contentOffset withTimingFunction:(CAMediaTimingFunction *)timingFunction duration:(CFTimeInterval)duration;

就像私有 API 但具有所有公共方法和数学。

于 2013-02-14T03:10:53.347 回答