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/
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