UIScrollview setContentOffset与非线性animation?

我试图重新生成滚动视图的平滑animation,当您实际滚动到下一页时启用分页。 它似乎是UIViewAnimationCurveEaseInOut ,但我需要有一个“下一页”button,并以编程方式触发滚动。

这是我的代码:

 -(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平滑…它进入下一个页面,一个丑陋的线性animation

我甚至试图手动animation:

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

我错在哪里?

每次你做自己的animation,你必须通过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]; } 

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

 - (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; } }]; } } 

我可以按照预期证实这一点,我自己testing了一下。

 [UIView animateWithDuration:(Animation_Duration) delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ [scroll setContentOffset:CGPointMake(PointX, PointY) animated:NO]; } completion:^(BOOL finished){}];` 

这个class绝对拯救了我的生命:

MOS在GitHub.com上

它有

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

就像私人的API,但所有的公共方法和math。