Creating slow scrolling to indexPath in UICollectionView Creating slow scrolling to indexPath in UICollectionView ios ios

Creating slow scrolling to indexPath in UICollectionView


You can try this approach:

@property (nonatomic, assign) CGPoint scrollingPoint, endPoint;@property (nonatomic, strong) NSTimer *scrollingTimer;@synthesize scrollingPoint, endPoint;@synthesize scrollingTimer;- (void)scrollSlowly {    // Set the point where the scrolling stops.    self.endPoint = CGPointMake(0, 300);    // Assuming that you are starting at {0, 0} and scrolling along the x-axis.    self.scrollingPoint = CGPointMake(0, 0);    // Change the timer interval for speed regulation.     self.scrollingTimer = [NSTimer scheduledTimerWithTimeInterval:0.015 target:self selector:@selector(scrollSlowlyToPoint) userInfo:nil repeats:YES];}- (void)scrollSlowlyToPoint {    self.collectionView.contentOffset = self.scrollingPoint;    // Here you have to respond to user interactions or else the scrolling will not stop until it reaches the endPoint.    if (CGPointEqualToPoint(self.scrollingPoint, self.endPoint)) {        [self.scrollingTimer invalidate];    }    // Going one pixel to the right.    self.scrollingPoint = CGPointMake(self.scrollingPoint.x, self.scrollingPoint.y+1);}


I use a "1 pixel offset" trick. When scrolling programmatically, just set the end contentOffset.x to 1 pixel more/less than it should. This should be unnoticeable. And in completion block set it to actual value. That way you can avoid the premature cell dequeuing problem and get smooth scrolling animation ;)

Here is an example of scrolling to the right page (e.g. from page 1 to 2). Notice that in the animations: block I actually scrolls one pixel less (pageWidth * nextPage - 1). I then restore the correct value in the completion: block.

CGFloat pageWidth = self.collectionView.frame.size.width;int currentPage = self.collectionView.contentOffset.x / pageWidth;int nextPage = currentPage + 1;[UIView animateWithDuration:1                      delay:0                    options:UIViewAnimationOptionCurveEaseOut                 animations:^{                     [self.collectionView setContentOffset:CGPointMake(pageWidth * nextPage - 1, 0)];                 } completion:^(BOOL finished) {                     [self.collectionView setContentOffset:CGPointMake(pageWidth * nextPage, 0)];                 }];


You could also have a "slow" scroll to the end of you UICollectionView without having to "jump" from indexpath to indexpath. I created this quickly for a collection view on a TVOS app:

func autoScroll () {    let co = collectionView.contentOffset.x    let no = co + 1    UIView.animateWithDuration(0.001, delay: 0, options: .CurveEaseInOut, animations: { [weak self]() -> Void in        self?.collectionView.contentOffset = CGPoint(x: no, y: 0)        }) { [weak self](finished) -> Void in            self?.autoScroll()    }}

I just call the autoScroll() in the viewDidLoad() and the rest takes care of it itself. The speed of the scrolling is decided by the animation time of the UIView. You could (I haven't tried) add an NSTimer with 0 seconds instead so you can invalidate it on userscroll.