I have UICollectionView
Horizontal Image listing codes. I want to add PageControl
when scrolling images will shows, I added pagecontrol selector and IBOutlet
but how can I integrate it between UICollecitonView
?
My codes are below:
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var View : DesignableView!
@IBOutlet var collectionView: UICollectionView!
@IBOutlet var collectionViewLayout: UICollectionViewFlowLayout!
@IBOutlet open weak var pageControl: UIPageControl? {
didSet {
pageControl?.addTarget(self, action: #selector(ViewController.pageChanged(_:)), for: .valueChanged)
}
}
override func viewDidLoad() {
super.viewDidLoad()
pageControl?.numberOfPages = 11
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 11;
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: ImageCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCollectionViewCell", for: indexPath) as! ImageCollectionViewCell
cell.label.text = "Cell \(indexPath.row)"
cell.backgroundImageView.image = UIImage(named: "Parallax \(indexPath.row + 1)")
// Parallax cell setup
cell.parallaxTheImageViewScrollOffset(self.collectionView.contentOffset, scrollDirection: self.collectionViewLayout.scrollDirection)
return cell
}
@IBAction open func pageChanged(_ sender: UIPageControl) {
print(sender.currentPage)
}
// MARK: Delegate
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return collectionView.bounds.size;
}
// MARK: Scrolling
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Parallax visible cells
for cell: ImageCollectionViewCell in collectionView.visibleCells as! [ImageCollectionViewCell] {
cell.parallaxTheImageViewScrollOffset(self.collectionView.contentOffset, scrollDirection: self.collectionViewLayout.scrollDirection)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I'm not a fan of the accepted answer. From time to time, willDisplay cell
will return the wrong page for the page control depending on users interaction.
What I use:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
pageControl.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}
This will update the page after the user has finished scrolling thus making the currentPage
of the pageControl
more accurate.
Here you have a complete class with Page Control pagination in a horizontal collection view. This is working on one of my applications, right now, and is working correctly. If you cannot get it work, do feel free to ask me and I'll help you.
First, in the Storyboard you have to set up your CollectionView with:
Layout: Flow
Scroll Direction: Horizontal
Scrolling enabled
Paging enabled
@IBOutlet weak var collectionView: UICollectionView! //img: 77
@IBOutlet weak var pageControl: UIPageControl!
var thisWidth:CGFloat = 0
override func awakeFromNib() {
super.awakeFromNib()
thisWidth = CGFloat(self.frame.width)
collectionView.delegate = self
collectionView.dataSource = self
pageControl.hidesForSinglePage = true
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YourCell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
self.pageControl.currentPage = indexPath.section
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
thisWidth = CGFloat(self.frame.width)
return CGSize(width: thisWidth, height: self.frame.height)
}
For a more responsive UIPageControl, I prefer to use scrollViewDidScroll
and calculating the offset with regards to the horizontal center of the scrollView.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offSet = scrollView.contentOffset.x
let width = scrollView.frame.width
let horizontalCenter = width / 2
pageControl.currentPage = Int(offSet + horizontalCenter) / Int(width)
}
Swift 5 Very Smooth working
//MARK:- For Display the page number in page controll of collection view Cell
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let visibleRect = CGRect(origin: self.collectionview.contentOffset, size: self.collectionview.bounds.size)
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
if let visibleIndexPath = self.collectionview.indexPathForItem(at: visiblePoint) {
self.pageControl.currentPage = visibleIndexPath.row
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With