iOS/UIKit
[UIKit] : CollectionView Header 만들기 - (UICollectionReusableView)
SeorinY
2022. 9. 2. 16:49
Collection View에서 UICollectionReusableView를 사용하여 header를 만들어보자.
전 글에서 CollectionView 를 만들었으니 코드를 이어서 작성해보자!
참고 : https://seorin-yy.tistory.com/19
[Swift] : CollectionView 생성, Cell 등록하기
정말 많이 사용되는 CollectionView 를 띄워보자. Collection View 를 생성하기 전에 먼저 CollectionView 에서 사용될 Cell 을 만들어보자 UICollectionViewCell를 상속받는 Cell을 생성해주자. 그리고 알 수..
seorin-yy.tistory.com
UICollectionReusableView를 사용하여 Header를 만들게 되면 각 Section마다 Header가 생성될 것이다.
먼저 UICollectionReusableView를 사용해서 header 뷰를 만들어보자!
class HeaderCollectionReusableView: UICollectionReusableView {
static let identifier = "HeaderCollectionReusableView"
//Header를 알려줄 label
private let label : UILabel = {
let label = UILabel()
label.text = "Header"
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(label)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
label.frame = CGRect(x: 20, y: 0, width: 100, height: 30)
}
}
이제 HeaderCollectionReusableView를 사용할 ViewController에서 HeaderCollectionReusableView를 등록해주자.
viewDidLoad에 아래 코드를 추가해주자
collectionView?.register(HeaderCollectionReusableView.self,
forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
withReuseIdentifier: HeaderCollectionReusableView.identifier)
그리고 UICollectionViewDelegateFlowLayout 를 사용하여 header를 띄워주고 크기를 정해주자!
아래 함수를 정의해주면 된다
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
guard kind == UICollectionView.elementKindSectionHeader else{
return UICollectionReusableView()
}
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: HeaderCollectionReusableView.identifier, for: indexPath) as! HeaderCollectionReusableView
return headerView
}
//layout 을 쳐서 referenceSizeForHeaderInsection 을 사용해서 Reusable View 의 크기를 정해주자 - 바로 리턴하면 됨
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: 300, height: 50)
}
이제 실행하면 위 결과처럼 잘 나올 것이다.
전체코드
import UIKit
class ViewController: UIViewController{
//collectionView를 생성해주자
private var collectionView : UICollectionView?
override func viewDidLoad() {
super.viewDidLoad()
configureCollectionView()
}
private func configureCollectionView(){
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.itemSize = CGSize(width: 50 , height:50)
layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
//위 layout들로 UICollectionView를 생성해주자
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView?.backgroundColor = .systemBackground
//collectionView에서 사용하고 싶은 cell을 identifier를 사용하여 등록해주자!!
collectionView?.register(CollectionViewCell.self, forCellWithReuseIdentifier: CollectionViewCell.identifier)
//collectionView에서 사용하고 싶은 Header를 identifier를 사용하여 등록해주자!!
collectionView?.register(HeaderCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: HeaderCollectionReusableView.identifier)
collectionView?.delegate = self
collectionView?.dataSource = self
guard let collectionView = collectionView else {
return
}
view.addSubview(collectionView)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView?.frame = view.bounds
}
}
extension ViewController : UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CollectionViewCell.identifier, for: indexPath) as? CollectionViewCell else { return UICollectionViewCell() }
return cell
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 3
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
guard kind == UICollectionView.elementKindSectionHeader else{
return UICollectionReusableView()
}
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: HeaderCollectionReusableView.identifier, for: indexPath) as! HeaderCollectionReusableView
return headerView
}
//layout 을 쳐서 referenceSizeForHeaderInsection 을 사용해서 Reusable View 의 크기를 정해주자 - 바로 리턴하면 됨
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: 300, height: 50)
}
}
class CollectionViewCell: UICollectionViewCell {
static let identifier = "CollectionViewCell"
override init(frame: CGRect) {
super.init(frame: frame)
//Cell에서는 View대신 ContentView를 사용한다
contentView.backgroundColor = .blue
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class HeaderCollectionReusableView: UICollectionReusableView {
static let identifier = "HeaderCollectionReusableView"
//Header를 알려줄 label
private let label : UILabel = {
let label = UILabel()
label.text = "Header"
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(label)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
label.frame = CGRect(x: 20, y: 0, width: 100, height: 30)
}
}