Search code examples
iosscrolluiviewanimationnsindexpathuicollectionview

Creating slow scrolling to indexPath in UICollectionView


I'm working on a project where I'm using a UICollectionView to create an 'image ticker' where I'm advertising a series of logos. The collectionView is one item high and twelve items long, and shows two to three items at a time (depending on size of the logos visible).

I would like to make a slow automatic scrolling animation from the first item to the last, and then repeat.

Has anyone been able to make this work? I can get the scrolling working using

[myCollection scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:(myImages.count -1) inSection:0] atScrollPosition:UICollectionViewScrollPositionRight animated:YES];

But this is way too fast!

[UIView animateWithDuration:10 delay:2 options:(UIViewAnimationOptionAutoreverse + UIViewAnimationOptionRepeat) animations:^{
    [myCollection scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:(myImages.count -1) inSection:0] atScrollPosition:UICollectionViewScrollPositionRight animated:NO];
} completion:nil];

This yields the desired scrolling speed, but only the last few cells are visible in the series. I suspect they (and even the starting visible cells) are being dequeued immediately.

Any thoughts?


Solution

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