Creating slow scrolling to indexPath in UICollectionView

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