앞서 기본적인 UICollectionViewDiffableDataSource에 대해 설명한 포스팅과 이어집니다~!
class MovieListHeaderView: UICollectionReusableView {
lazy var label: UILabel = {
let label = UILabel()
label.textColor = .white
label.font = .preferredFont(forTextStyle: .title1)
label.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(label)
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setConstraints()
}
required init?(coder: NSCoder) {
fatalError("Not Implemented")
}
override func prepareForReuse() {
super.prepareForReuse()
initialize()
}
func initialize() {
self.label.text = nil
}
func setConstraints() {
NSLayoutConstraint.activate([
self.label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 15),
self.label.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 10),
self.label.topAnchor.constraint(equalTo: self.topAnchor, constant: 15),
self.label.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 10)
])
}
}
생성한 애를 사용하려면 register 해줘야겠지?
self.collectionView.register(
MovieListHeaderView.self,
forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
withReuseIdentifier: "MovieListHeaderView")
dataSource의 supplementaryViewProvider 프로퍼티에 해당 headerView가 속한 collectionView와 indexPath가 넘어오는데,
collectionView로는 dequeueReusableSupplementaryView 를 통해 등록한 supplementaryView를 꺼내오고
indexPath로는... 해당 headerview의 section이 뭔지 알 수 있다 ㅎ
indexPath로 dataSource의 snapshot에서 해당하는 section 데이터를 가져와 앞서 꺼낸 headerview의 title을 설정해준다.
self.movieListDataSource.supplementaryViewProvider = { (collectionView, kind, indexPath) in
guard let header = collectionView.dequeueReusableSupplementaryView(
ofKind: UICollectionView.elementKindSectionHeader,
withReuseIdentifier: "MovieListHeaderView",
for: indexPath) as? MovieListHeaderView else {
return MovieListHeaderView()
}
let section = self.movieListDataSource.snapshot().sectionIdentifiers[indexPath.section]
header.label.text = section.description
return header
}
레이아웃은 앞 포스팅에서 기본적으로 설정해준 것을 바탕으로
section 부분에만 headerView를 추가해주면 된다.
section.boundarySupplementaryItems를 설정해주면 완료~!
private func createLayout() -> UICollectionViewLayout {
let itemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets = NSDirectionalEdgeInsets(
top: 20,
leading: 20,
bottom: 20,
trailing: 20)
let groupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalWidth(1.0))
let group = NSCollectionLayoutGroup.horizontal(
layoutSize: groupSize,
subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .paging
section.interGroupSpacing = 0
//요기
let headerSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(44))
let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: headerSize,
elementKind: UICollectionView.elementKindSectionHeader,
alignment: .top)
section.boundarySupplementaryItems = [sectionHeader]
let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}
Custom Header
Developer Documentation: SupplementaryViewProvider