Skip to content

Instantly share code, notes, and snippets.

@michaelevensen
Last active April 10, 2024 08:46
Show Gist options
  • Star 38 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save michaelevensen/e5f756c74b8eb992836fc596056a43d1 to your computer and use it in GitHub Desktop.
Save michaelevensen/e5f756c74b8eb992836fc596056a43d1 to your computer and use it in GitHub Desktop.
An example of perfectly paging horizontal UICollectionViewController with overflowing cells. Works great with Storyboard — no need to set any specific attributes, just add this Class to the Controller and set your desired size for the cells like you would normally.
import UIKit
private let reuseIdentifier = "Cell"
class CollectionViewController: UICollectionViewController {
/* Custom scrollView for paging */
let pagingScrollView = UIScrollView()
/* Return item size */
var itemSize: CGSize {
let layout = self.collectionViewLayout as! UICollectionViewFlowLayout
return layout.itemSize
}
/* Return spacing: Interitem */
var interItemSpacing: CGFloat {
let layout = self.collectionViewLayout as! UICollectionViewFlowLayout
return layout.minimumInteritemSpacing
}
/* Get section inset */
var sectionInset: UIEdgeInsets {
let layout = self.collectionViewLayout as! UICollectionViewFlowLayout
return layout.sectionInset
}
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Override native UICollectionView scrollView events
if scrollView == self.pagingScrollView {
var contentOffset = scrollView.contentOffset
// Include offset from left
if let contentOffsetX = self.collectionView?.contentInset.left {
contentOffset.x = contentOffset.x - contentOffsetX
self.collectionView?.contentOffset = contentOffset
}
}
}
// MARK: - Initialize scrollView with proper size and frame
func initScrollView() {
// Get UICollectionView frame
if let collectionViewFrame = self.collectionView?.frame {
// Set proper frame
self.pagingScrollView.frame = collectionViewFrame
self.pagingScrollView.isHidden = true
// Enable paging
self.pagingScrollView.isPagingEnabled = true
// Set delegate
self.pagingScrollView.delegate = self
// Set bounds for scrollView
self.pagingScrollView.bounds = CGRect(x: 0, y: 0, width: self.itemSize.width + self.interItemSpacing, height: collectionViewFrame.size.height)
// Number of items in UICollectionView
if let numberOfItemsInCollectionView = self.collectionView?.numberOfItems(inSection: 0) {
// Calculcate full width (with spacing) for contentSize
let collectionViewWidth = CGFloat(numberOfItemsInCollectionView) * (self.itemSize.width + self.interItemSpacing)
// Set contentSize
self.pagingScrollView.contentSize = CGSize(width: collectionViewWidth, height: view.frame.size.height)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Initialize Paging scrollView
self.initScrollView()
// Add custom paging scrollView
self.view.addSubview(self.pagingScrollView)
// Disable standard gesture recognizer for UICollectionView scrollView and add custom
self.collectionView?.addGestureRecognizer(self.pagingScrollView.panGestureRecognizer)
self.collectionView?.panGestureRecognizer.isEnabled = false
}
// MARK: UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
return cell
}
}
@SaidRs
Copy link

SaidRs commented Jul 25, 2022

Excellent work, thanks!

@dikshaGaonkar
Copy link

just add this Class to the Controller and set your desired size for the cells like you would normally.
how?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment