🔍 createDataSource() { }
이 메서드는 UICollectionViewDiffableDataSource를 생성하고, 셀과 섹션 헤더를 설정하는 역할
- dataSource = UICollectionViewDiffableDataSource<TvTMDBData, TvResultItem>
- 섹션 타입: TvTMDBData
- 아이템 타입: TvResultItem
- → 각 섹션(TvTMDBData) 안에 여러 개의 아이템(TvResultItem)이 포함된다.
- 셀을 생성 및 구성
- switch sectionType을 사용하여 각 섹션별로 다른 셀을 반환함.
- configure(_:with:for:) 메서드를 사용해 적절한 셀을 생성하고 데이터를 적용.
- 섹션 헤더를 설정
- dataSource?.supplementaryViewProvider를 사용해 섹션별 헤더 뷰를 구성함.
- 섹션 정보를 가져와 TVSectionHeader에 적용.
private func createDataSource() {
dataSource = UICollectionViewDiffableDataSource<TvTMDBData, TvResultItem>(collectionView: seriesCollectionView) { collectionView, indexPath, item in
let tvTMDBResult = item.tvResult
let sectionType = self.tvCombineSection.combineTMDB[indexPath.section].type ?? .popular
switch sectionType {
case .airingToday:
return self.configure(TvFeaturedCell.self, with: tvTMDBResult, for: indexPath)
case .onTheAir:
return self.configure(TVMediumCell.self, with: tvTMDBResult, for: indexPath)
case .popular:
return self.configure(TvFeaturedCell.self, with: tvTMDBResult, for: indexPath)
case .topRated:
return self.configure(TVSmallCell.self, with: tvTMDBResult, for: indexPath)
}
}
dataSource?.supplementaryViewProvider = { [weak self] collectionView, kind, indexPath in
guard let sectionHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: TVSectionHeader.reuseIdentifier, for: indexPath) as? TVSectionHeader else { return nil }
guard let firstItem = self?.dataSource?.itemIdentifier(for: indexPath) else { return nil }
guard let section = self?.dataSource?.snapshot().sectionIdentifier(containingItem: firstItem) else { return nil }
switch section.type {
case .airingToday:
let mainTitle = section.type?.rawValue
let subTitle = "오늘 방영중 TV"
sectionHeader.configure(with: mainTitle!, sub: subTitle)
case .onTheAir:
let mainTitle = section.type?.rawValue
let subTitle = "현재 방영 중인 TV"
sectionHeader.configure(with: mainTitle!, sub: subTitle)
case .popular:
let mainTitle = section.type?.rawValue
let subTitle = "인기 TV"
sectionHeader.configure(with: mainTitle!, sub: subTitle)
case .topRated:
let mainTitle = section.type?.rawValue
let subTitle = "순위 별 TV"
sectionHeader.configure(with: mainTitle!, sub: subTitle)
case .none:
return nil
}
return sectionHeader
}
}
🛠 1. dataSource 정의 부분 분석
dataSource = UICollectionViewDiffableDataSource<TvTMDBData, TvResultItem>(collectionView: seriesCollectionView) { collectionView, indexPath, item in
💡 각 파라미터의 의미
- collectionView → seriesCollectionView 인스턴스 (컬렉션뷰 자체)
- indexPath → 현재 렌더링할 셀의 섹션과 행(아이템)의 위치 정보
- item → TvResultItem 인스턴스로, 컬렉션 뷰의 특정 셀에 표시할 데이터
let tvTMDBResult = item.tvResult
let sectionType = self.tvCombineSection.combineTMDB[indexPath.section].type ?? .popular
- tvTMDBResult → 해당 TvResultItem에서 실제 TV 프로그램 정보를 가져옴.
- sectionType → indexPath.section을 기준으로 현재 섹션이 어떤 타입인지 확인.
🛠 2. dataSource?.supplementaryViewProvider(섹션 헤더 설정)
dataSource?.supplementaryViewProvider = { [weak self] collectionView, kind, indexPath in
💡 각 파라미터의 의미
- collectionView → 컬렉션뷰 자체
- kind → 보조 뷰의 종류 (헤더인지 푸터인지 결정)
- indexPath → 현재 헤더가 속한 섹션의 위치 정보
✅ 헤더 뷰를 가져오기
guard let sectionHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: TVSectionHeader.reuseIdentifier, for: indexPath) as? TVSectionHeader else { return nil }
- dequeueReusableSupplementaryView를 사용해 TVSectionHeader를 재사용
✅ 섹션 타입 가져오기
guard let firstItem = self?.dataSource?.itemIdentifier(for: indexPath) else { return nil }
guard let section = self?.dataSource?.snapshot().sectionIdentifier(containingItem: firstItem) else { return nil }
- firstItem → 해당 섹션에 속한 첫 번째 아이템을 가져옴
- section → 현재 아이템이 속한 섹션(TvTMDBData)을 가져옴
🔍 snapshot().sectionIdentifier(containingItem:)의 역할
guard let section = self?.dataSource?.snapshot().sectionIdentifier(containingItem: firstItem) else { return nil }
📌 1. snapshot()
- dataSource?.snapshot() → UICollectionViewDiffableDataSource의 **현재 데이터 상태(스냅샷)**를 가져옴.
- snapshot은 NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> 타입이며,
현재 컬렉션뷰가 표시하고 있는 모든 섹션 및 아이템의 계층 구조를 포함하고 있음.
📌 2. sectionIdentifier(containingItem:)
- snapshot.sectionIdentifier(containingItem: firstItem)
→ 특정 아이템(firstItem)이 속한 섹션을 찾아서 반환. - 즉, firstItem이 현재 속해 있는 TvTMDBData(섹션) 인스턴스를 반환함.
✅ 이걸 통해 현재 섹션이 무엇인지 알 수 있음!
✅ 그래서 섹션 타입(TvSectionType)을 꺼내와서 switch 문으로 헤더 제목을 설정하는 것.
'Project > MovieClip' 카테고리의 다른 글
📍 함수의 역할 -> createFeaturedSection() { } (0) | 2025.02.21 |
---|---|
📍함수의 역할 -> reloadData() { } (0) | 2025.02.21 |
📍함수의 역할 -> configure<T: SelfConfiguringTVCell> () { } (0) | 2025.02.21 |
🤔 영화 정보를 통합해서 관리할 필요가 있나? (0) | 2025.02.21 |
✅ hash(into:) 메서드와 == 연산자의 역할 (0) | 2025.02.20 |