개발/Swift

Compositional Layout + Diffable DataSource - 2 헤더 추가하기

덤벨로퍼 2022. 11. 27. 15:35

헤더 추가하기

우선 새로운 타입 sqaure carousel 섹션을 추가했다.

여기서는 새로운 타입의 아이템을 넣어줬다.

enum Item: Hashable {
    case banner(HomeItem)
    case normalCarousel(HomeItem)
    case squareCarousel(RestaurantItem)
}

struct RestaurantItem: Hashable {
    let name: String
    let reviewPoint: Float
    let reviewCount: Int
    let imageUrl: String
}

이러면 데이터소스에 넣어줄때 RestaurantItem 타입을 넣어주고

cell 그릴때 RestaurantItem 타입의 데이터를 받아 사용할수 있다.

//스냅샷 부분
snapshot.appendSections([Section(id: "sqaureCarousel")])
snapshot.appendItems([
    Item.squareCarousel(RestaurantItem(name: "버거슬럽", reviewPoint: 4.9, reviewCount: 235,imageUrl: placeHolderUrl)),
    Item.squareCarousel(RestaurantItem(name: "남도반주", reviewPoint: 4.7, reviewCount: 125,imageUrl: placeHolderUrl)),
    Item.squareCarousel(RestaurantItem(name: "아모르미오", reviewPoint: 5.0, reviewCount: 863,imageUrl: placeHolderUrl)),
    Item.squareCarousel(RestaurantItem(name: "두 셰프의 무회", reviewPoint: 4.9, reviewCount: 2637,imageUrl: placeHolderUrl)),
    Item.squareCarousel(RestaurantItem(name: "남성역골목시장 수라축산", reviewPoint: 4.9, reviewCount: 179,imageUrl: placeHolderUrl))
])

//Cell 리턴하는 부분
case .squareCarousel(let data):
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SqaureCarouselCell", for: indexPath) as? SquareCarouselCollectionViewCell else {fatalError()}
    cell.configure(title: data.name, url: data.imageUrl, review: "\\(data.reviewPoint)(\\(data.reviewCount))")
    return cell

}

여기까지는 기존이랑 비슷하다. 여기서 해당 섹션에만 헤더를 추가하려 한다.

collectionView.register(SqaureCarouselHeaderView.self, forSupplementaryViewOfKind: "SqaureCarouselHeader", withReuseIdentifier: "SqaureCarouselHeader")

SqaureCarouselHeaderView 를 구현해놨고 이를 등록한 후에 datasource - supplementaryViewProvider 를 정의해놔야한다.

dataSource?.supplementaryViewProvider = { (collectionView, kind, indexPath) -> UICollectionReusableView in
  guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "SqaureCarouselHeader", for: indexPath) as? SqaureCarouselHeaderView else { fatalError()}
  header.configure(title: "이츠 오리지널", desc: "쿠팡이츠에서 먼저 맛볼 수 있는 맛집입니다")
  return header
}

지금은 고정된 값이지만 동적으로 configure을 하려면 내부적으로 데이터를 가지고있고 indexpath를 통해

접근해야 할것같다.

그리고 헤더가 필요한 섹션에만 레이아웃에 아래와같이 헤더가 추가해주면 된다.

private func createSqaureCarouselSection() -> NSCollectionLayoutSection {
		//헤더
    let headerSize  = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(44))
    let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: "SqaureCarouselHeader", alignment: .topLeading)
    let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1.0))
    let item = NSCollectionLayoutItem(layoutSize: itemSize)
    item.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 15)

    let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.65), heightDimension: .estimated(200))

    let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])

    let section = NSCollectionLayoutSection(group: group)
    section.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 20, bottom: 0, trailing: 20)
		//헤더 추가    
		section.boundarySupplementaryItems = [header]
    section.orthogonalScrollingBehavior = .continuous
    return section

}

결과