섹션을 정의한다.
enum Section: Int, CaseIterable {
case category
case product
case circleItem
}
컬렉션뷰를 생성하고 사용할 셀과 헤더뷰를 등록해준다.
private var collectionView: UICollectionView!
collectionView.register(CategoryCell.self, forCellWithReuseIdentifier: "CategoryCell")
collectionView.register(ProductCell.self, forCellWithReuseIdentifier: "ProductCell")
collectionView.register(CircleItemCell.self, forCellWithReuseIdentifier: "CircleItemCell")
collectionView.register(ItemHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HeaderView")
레이아웃을 설정한다.
collectionView.collectionViewLayout = getLayout()
func getLayout() -> UICollectionViewCompositionalLayout {
let layout = UICollectionViewCompositionalLayout { (section, env) -> NSCollectionLayoutSection? in
switch section {
// Title 섹션
case 0:
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.25), heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 12, bottom: 0, trailing: 12)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(68))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 14, bottom: 16, trailing: 14)
return section
// Product 섹션
case 1:
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(240), heightDimension: .estimated(316))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.interGroupSpacing = 10
section.contentInsets = NSDirectionalEdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 20)
section.orthogonalScrollingBehavior = .continuous
return section
// CircleItem 섹션
case 2:
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(80), heightDimension: .estimated(130))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
// SupplementaryView로 HeaderView 레이아웃설정
let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(60.0))
let header = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: headerSize,
elementKind: UICollectionView.elementKindSectionHeader,
alignment: .top
)
let section = NSCollectionLayoutSection(group: group)
section.interGroupSpacing = 10
section.contentInsets = NSDirectionalEdgeInsets(top: 5, leading: 25, bottom: 24, trailing: 25)
section.orthogonalScrollingBehavior = .continuous
// HeaderView 등록
section.boundarySupplementaryItems = [header]
section.supplementariesFollowContentInsets = false
// DecoView 생성
let decorationView = NSCollectionLayoutDecorationItem.background(elementKind: "DecoView")
section.decorationItems = [decorationView]
return section
default:
return nil
}
}
// DecorationView 등록
layout.register(DecoView.self, forDecorationViewOfKind: "DecoView")
return layout
}
// HeaderView 설정
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionView.elementKindSectionHeader:
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "HeaderView", for: indexPath) as! ItemHeaderView
return header
default:
return UICollectionReusableView()
}
}
DataSource를 설정한다.
collectionView.dataSource = self
// numberOfSections 메소드 구현 (섹션 개수)
func numberOfSections(in collectionView: UICollectionView) -> Int {
return Section.allCases.count
}
// numberOfItemsInSection 메소드 구현 (섹션의 row 개수)
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
switch Section(rawValue: section) {
case .category:
return categoryImage.count
case .product:
return productList.count
case .circleItem:
return circleItemList.count
case .none:
return 0
}
}
// cellForItemAt 메소드 구현 (셀 내용)
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let currentSection = Item(rawValue: indexPath.section)
switch currentSection {
case .category:
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoryCell", for: indexPath) as? CategoryCell else { return UICollectionViewCell()}
cell.titleButton.setImage(categoryImage[indexPath.row], for: .normal)
return cell
case .product:
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ProductCell", for: indexPath) as? ProductCell else { return UICollectionViewCell() }
let product = productList[indexPath.row]
cell.productImageView.image = product.image
cell.contentTitleLabel.text = product.title
cell.ratingLabel.text = product.rating
cell.reviewCountLabel.text = "(\(product.reviewCount))"
cell.locationLabel.text = product.location
cell.priceLabel.text = product.price
return cell
case .circleItem:
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CircleItemCell", for: indexPath) as? CircleItemCell else { return UICollectionViewCell() }
let item = circleItemList[indexPath.row]
cell.circleImageView.image = item.image
cell.circleItemLabel.text = item.title
return cell
case .none:
return UICollectionViewCell()
}
}