Reputation: 8687
I have 15 categories that I want to show on the screen. I want to do the following
Someone said using collection view compositional layout is the way to go. Here's what I have so far. Unfortunately, it's not rendering the categories properly. See screenshot.
import UIKit
class CategoriesViewController: UIViewController, UICollectionViewDataSource {
var categories = ["Category 1", "Category 2", "Category 3", "Category 4", "Category 5",
"Category 6", "Category 7", "Category 8", "Category 9", "Category 10"]
var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
// Initialize collection view with a compositional layout
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createLayout())
collectionView.dataSource = self
collectionView.register(CategoryCell.self, forCellWithReuseIdentifier: "CategoryCell")
collectionView.backgroundColor = .white
view.addSubview(collectionView)
}
// MARK: - Compositional Layout
func createLayout() -> UICollectionViewLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.2), heightDimension: .absolute(50))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
// Add spacing between items
item.contentInsets = NSDirectionalEdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(60))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.interGroupSpacing = 10
let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}
// MARK: - UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return categories.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoryCell", for: indexPath) as! CategoryCell
cell.configure(with: categories[indexPath.item])
return cell
}
}
Upvotes: 0
Views: 85
Reputation: 9
I have the same issue and this is how I can fix it.
But remember to choose Collection View -> Size Inspector -> Estimate Size set to None.
This will let you conform to UICollectionViewDelegateFlowLayout.
extension BaseViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 8
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 8
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemWidth = ((collectionView.bounds.width - 16)/3)
return CGSize(width: itemWidth, height: itemWidth * 235/125)
}
}
If you have 3 items in a row, the spacing between items is 8. The width of each item is calculated as: Width = (CollectionView.Width - 16) / 3. For 5 items, the formula becomes: Width = (CollectionView.Width - 32) / 5.
235/125 represents the ratio of your cell:
let itemWidth = ((collectionView.bounds.width - 16)/3)
return CGSize(width: itemWidth, height: itemWidth * 235/125)
Upvotes: 0