Last active
April 10, 2024 08:46
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
just add this Class to the Controller and set your desired size for the cells like you would normally.
how?