How to connect UIPageControl to UICollectionView (Swift)

Step 1 Create the variables for Collection View and Page Control

@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet var pageControl:UIPageControl!     

Step 2 Set the number of pages of Page Control

override func viewDidLoad() {
    super.viewDidLoad()         
    self.pageControl.numberOfPages = procedures.count
    //Set the delegate
    self.collectionView.delegate = self
}

*Step 3 In the scrollViewDidScroll function calculate the width of collection cell and the index for the current page.

    extension YourCollectionVC: UICollectionViewDataSource, UICollectionViewDelegate {
            override func scrollViewDidScroll(_ scrollView: UIScrollView) {
                let witdh = scrollView.frame.width - (scrollView.contentInset.left*2)
                let index = scrollView.contentOffset.x / witdh
                let roundedIndex = round(index)
                self.pageControl?.currentPage = Int(roundedIndex)
            }
}

Note: This is for collection view displayed horizontally, for vertical direccion change the method.

Tested in swift 4.


Firstly add your UIPageControl into your storyboard with your UICollectionView, then connect them as outlets to your view controller.

@IBOutlet var pageControl: UIPageControl!
@IBOutlet var collectionView: UICollectionView!

Adjust your numberOfItemsInSection method in UICollectionViewDataSource to set the count of the page control to always be equal to the number of cells in the collection view.

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

    let count = ...

    pageControl.numberOfPages = count
    pageControl.isHidden = !(count > 1)

    return count
}

Lastly, using the UIScrollViewDelegate, we can tell which cell the UICollectionView stops on. If you are not using a UICollectionViewController, you may have to add the delegate protocol.

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

    pageControl?.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}

func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {

    pageControl?.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}

This is possible because a UICollectionView is in fact a UIScrollView under the hood.


Use this for smooth functioning.

 func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let witdh = scrollView.frame.width - (scrollView.contentInset.left*2)
    let index = scrollView.contentOffset.x / witdh
    let roundedIndex = round(index)
    self.pageControl.currentPage = Int(roundedIndex)
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

    pageControl.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}

func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {

    pageControl.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}