Creating slow scrolling to indexPath in UICollectionView

convert uitableview to uicollectionview
uicollectionview scroll to item
uicollectionview scroll delegate
scroll uicollectionview programmatically swift 4
uicollectionview horizontal scroll programmatically swift
uicollectionview image scroll performance
auto scrolling uicollectionview swift
uicollectionview scroll to top

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?

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

ios Creating slow scrolling to indexPath in UICollectionView?, 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   I am trying to memorize an index for an item (indexPath.item) in a UICollectionView and at a later time, after the view is replaced and then restored, to scroll to that memorized item. When memorizing the item, indexPath, and indexPath.item are: indexPath is: <NSIndexPath 0x1d87b380> 2 indexes [0, 32] indexPath.item is: 32

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
                     [self.collectionView setContentOffset:CGPointMake(pageWidth * nextPage - 1, 0)];
                 } completion:^(BOOL finished) {
                     [self.collectionView setContentOffset:CGPointMake(pageWidth * nextPage, 0)];

Liquid smooth iOS collection view scrolling with, Liquid smooth iOS collection view scrolling with lots of images An class]) forIndexPath:indexPath]; CCCue *cue = self.cues[indexPath.item]; [cell was that when an image instantiated this way is rendered by setting on a UIImageView, and  I am trying to create a calendar view same as iOS but only for four years. The hierarchy is like: UICollectionView: One Section for each year UICollectionViewCell: 12 cells/items for 12 months in an year UICollectionView: UICollectionViewCell: Upto 31 cells for month day string, which have UILabel

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

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.

Smooth Scrolling in UITableView and UICollectionView, This step is paramount to achieving a very smooth scrolling experience. Tips Common to both UITableView and UICollectionView Basically, we should create appropriate Auto Layout constraints to make sure the UI  I have the following UICollectionView which is populated by an Array with NSManagedObject of type Categories. The problem is that when a Cell is selected scrolling does not function correctly. When scrolling through the UICollectionView other cells get selected, and deselected. Strange behaviour.

For anyone else finding this, I've updated Masa's suggestion to work on Swift and I've introduced a little bit of easing towards the end so it acts more like the original scrollItemsToIndexPath animated call. I have hundreds of items in my view so a steady pace wasn't an option for me.

var scrollPoint: CGPoint?
var endPoint: CGPoint?
var scrollTimer: NSTimer?
var scrollingUp = false

func scrollToIndexPath(path: NSIndexPath) {
    let atts = self.collectionView!.layoutAttributesForItemAtIndexPath(path)
    self.endPoint = CGPointMake(0, atts!.frame.origin.y - self.collectionView!
    self.scrollPoint = self.collectionView!.contentOffset
    self.scrollingUp = self.collectionView!.contentOffset.y > self.endPoint!.y

    self.scrollTimer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "scrollTimerTriggered:", userInfo: nil, repeats: true)

func scrollTimerTriggered(timer: NSTimer) {
    let dif = fabs(self.scrollPoint!.y - self.endPoint!.y) / 1000.0
    let modifier: CGFloat = self.scrollingUp ? -30 : 30

    self.scrollPoint = CGPointMake(self.scrollPoint!.x, self.scrollPoint!.y + (modifier * dif))
    self.collectionView?.contentOffset = self.scrollPoint!

    if self.scrollingUp && self.collectionView!.contentOffset.y <= self.endPoint!.y {
        self.collectionView!.contentOffset = self.endPoint!
    } else if !self.scrollingUp && self.collectionView!.contentOffset.y >= self.endPoint!.y {
        self.collectionView!.contentOffset = self.endPoint!

Tweaking the values of dif and modifier adjusts the duration/level of ease for most situations.

Prefetching Collection View Data, Load data for collection view cells before they are displayed. You use data prefetching when loading data is a slow or expensive process—for func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [ IndexPath]) { // Begin Create your own version of AsyncFetcher to fit your requirements. InfiniteGridDataSource.swift — IndexPath to GridCoordinates tracking. At line 4 we assign a value to our pathsCacheSize, while the exact value is not important it should be larger than the number of cells UICollectionView will have cached at any point in time. If this value is too small, some cells will not appear properly when scrolling.

In .h file, declare this timer,

NSTimer *Timer;

Place this timer code,

  [CollectionView reloadData];
  Timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(AutoScroll) userInfo:nil repeats:YES];


#pragma mark- Auto scroll image collectionview
    if (i<[Array count])
        NSIndexPath *IndexPath = [NSIndexPath indexPathForRow:i inSection:0];
        [self.ImageCollectionView scrollToItemAtIndexPath:IndexPath
            atScrollPosition:UICollectionViewScrollPositionRight animated:NO];
        if (i==[Array count])

Hope it'll be useful.

scrollToItemAtIndexPath:atScrollPosition:animated, Scrolls the collection view contents until the specified item is visible. Availability. iOS 6.0 indexPath. The index path of the item to scroll into view. scrollPosition. Home · iOS & Swift Tutorials UICollectionView Tutorial: Getting Started. In this tutorial, you’ll get hands-on experience with UICollectionView by creating your own grid-based photo browsing app.

UICollectionView Tutorial: Prefetching APIs, In this UICollectionView prefetching tutorial, you'll learn how to You can achieve smooth scrolling by making sure your app meets the 60 frames per second (FPS) display constraint. loadEmojiRating(at: indexPath.item) { cell. You create a DataLoadOperation() to fetch the emoji in the background. By default, your chat collectionview needs to show the latest messages at the top, so when you invert the UICollectionView the latest messages will be at the bottom, and when the user scroll to the top will get the older messages.

How to impove performance when scrolling UITableView , func tableView(_ tableView: UITableView, cellForRowAt indexPath: swift, xcode, ios, performance, scrolling, UITableView, UICollectionView. Inferring IndexPath for UICollectionView With the changes array returned by DeepDiff , we can infer the required set of IndexPath to feed to UICollectionView to perform the updates.

The next step is to create the cell (tab) for the UICollectionView. Create a new swift file, name it TabCell , and paste the following code: import UIKit class TabCell: UICollectionViewCell { private var tabSV: UIStackView!