How to programmatically scroll through a collection view?

24,710

Solution 1

There are two methods that could help you achieve this:

func scrollToItemAtIndexPath(indexPath: NSIndexPath,
        atScrollPosition scrollPosition: UICollectionViewScrollPosition,
                animated animated: Bool)

or

func setContentOffset(contentOffset: CGPoint,
         animated animated: Bool)

Both are on UICollectionView so you can use whatever seems more convenient. To create a custom animation for this however is more difficult. A quick solution depending on what you need could be this answer.

Swift 4, iOS 11:

// UICollectionView method
func scrollToItem(at indexPath: IndexPath, 
                  at scrollPosition: UICollectionViewScrollPosition,  
                  animated: Bool)

// UIScrollView method
func setContentOffset(_ contentOffset: CGPoint, animated: Bool)

Solution 2

Swift 5

Based on Mr.Bean's answer, here is an elegant way using UICollectionView extension:

extension UICollectionView {
    func scrollToNextItem() {
        let contentOffset = CGFloat(floor(self.contentOffset.x + self.bounds.size.width))
        self.moveToFrame(contentOffset: contentOffset)
    }

    func scrollToPreviousItem() {
        let contentOffset = CGFloat(floor(self.contentOffset.x - self.bounds.size.width))
        self.moveToFrame(contentOffset: contentOffset)
    }

    func moveToFrame(contentOffset : CGFloat) {
        self.setContentOffset(CGPoint(x: contentOffset, y: self.contentOffset.y), animated: true)
    }
}

Now you can use it wherever you want:

collectionView.scrollToNextItem()
collectionView.scrollToPreviousItem()

Solution 3

By far this is the best approach i have encountered, the trick is to scroll to the frame which is containing next objects. Please refer the code

/* -------------- display previous friends action ----------------*/
@IBAction func actionPreviousFriends(_ sender: Any) {

    let collectionBounds = self.collectionView.bounds
    let contentOffset = CGFloat(floor(self.collectionView.contentOffset.x - collectionBounds.size.width))
    self.moveToFrame(contentOffset: contentOffset)
}

/* -------------- display next friends action ----------------*/
@IBAction func actionNextFriends(_ sender: Any) {

    let collectionBounds = self.collectionView.bounds
    let contentOffset = CGFloat(floor(self.collectionView.contentOffset.x + collectionBounds.size.width))
    self.moveToFrame(contentOffset: contentOffset)
}

func moveToFrame(contentOffset : CGFloat) {

    let frame: CGRect = CGRect(x : contentOffset ,y : self.collectionView.contentOffset.y ,width : self.collectionView.frame.width,height : self.collectionView.frame.height)
    self.collectionView.scrollRectToVisible(frame, animated: true)
}

Solution 4

You can use this UICollectionView extension (Swift 4.2)

        extension UICollectionView {

        func scrollToNextItem() {
            let scrollOffset = CGFloat(floor(self.contentOffset.x + self.bounds.size.width))
            self.scrollToFrame(scrollOffset: scrollOffset)
        }

        func scrollToPreviousItem() {
            let scrollOffset = CGFloat(floor(self.contentOffset.x - self.bounds.size.width))
            self.scrollToFrame(scrollOffset: scrollOffset)
        }

        func scrollToFrame(scrollOffset : CGFloat) {
            guard scrollOffset <= self.contentSize.width - self.bounds.size.width else { return }
            guard scrollOffset >= 0 else { return }
            self.setContentOffset(CGPoint(x: scrollOffset, y: self.contentOffset.y), animated: true)
        }
    }

And the usage will be like

yourCollectionView.scrollToNextItem()
yourCollectionView.scrollToPreviousItem()
Share:
24,710
Lenny1357
Author by

Lenny1357

Updated on December 06, 2020

Comments

  • Lenny1357
    Lenny1357 over 3 years

    I have a collection view in my view. In the cells are image views and it has one section.

    I now want to scroll programmatically through the images. I want the animation to happen endless so it starts with item one after reaching item 10.

    It also would be helpful if you provide some method where to put animations like the cells getting bigger after getting programmatically swiped in from right.