Skip to content

Instantly share code, notes, and snippets.

@henning-jh
Last active December 9, 2018 08:53
Show Gist options
  • Save henning-jh/1933e5b671bdc640890934e93e00e619 to your computer and use it in GitHub Desktop.
Save henning-jh/1933e5b671bdc640890934e93e00e619 to your computer and use it in GitHub Desktop.
Basic UICollectionView with evenly spaced items.

Just as a reference, here's a UICollectionView with some nice evenly spaced cells.

class ViewController: UIViewController, UICollectionViewDataSource /*, UICollectionViewDelegate */ {

	let kReuseIdentifier = "CollectionCellID"
	let kNumCellsPerRow:CGFloat = 3.0
	let kSpacer:CGFloat = 10.0
	var collectionView : UICollectionView!
	
	override func viewDidLoad() {
		super.viewDidLoad()

		let cellsPerRow: CGFloat = kNumCellsPerRow
		let minItemSpacing: CGFloat = kSpacer
		let containerWidth: CGFloat = self.view.bounds.width 
		let itemWidth: CGFloat = (containerWidth - (cellsPerRow+1) * minItemSpacing) / cellsPerRow - 1	// -1 in case the screen width doesn't make it easy for us
		let inset = max(minItemSpacing, floor( (containerWidth - (cellsPerRow*itemWidth) - (cellsPerRow-1)*minItemSpacing) / 2 ) )
		let layout = UICollectionViewFlowLayout()
		
		layout.itemSize = CGSize(width: itemWidth, height: itemWidth)
		layout.minimumInteritemSpacing = minItemSpacing
		layout.minimumLineSpacing = minItemSpacing
		layout.sectionInset = UIEdgeInsets(top: minItemSpacing, left: inset, bottom: minItemSpacing, right: inset)

		self.collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout)
		collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: kReuseIdentifier)
		//collectionView.delegate = self
		collectionView.dataSource = self
		collectionView.backgroundColor = self.view.backgroundColor
		
		self.view.addSubview(collectionView)
	}
	
	func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
		return 20
	}
	
	func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
		let cell = collectionView.dequeueReusableCell(withReuseIdentifier: kReuseIdentifier, for: indexPath as IndexPath)
		cell.backgroundColor = UIColor.lightGray
		cell.layer.cornerRadius = 3.0
		return cell
	}
}

References:

https://stackoverflow.com/questions/17856055/creating-a-uicollectionview-programmatically

https://samwize.com/2015/11/30/understanding-uicollection-flow-layout/

@markckim
Copy link

markckim commented Dec 9, 2018

Thanks for sharing this code. I just wanted mention that I was occasionally getting issues with the "inset" calculation. For example, it wasn't working (for me) for kNumCellsPerRow = 3. It seems to make sense what you're doing and, perhaps, I was doing something wrong. However, I opted to take a similar approach to your "itemWidth" calculation and just subtract 1, which worked for me:

CGFloat inset = ((containerWidth - kNumCellsPerRow*itemWidth - (kNumCellsPerRow-1)*kSpacer) / 2) - 1

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