Header 고정

리스트를 UIKit으로 구현하는데는 UICollectionView / UITableView 둘 중 하나로 보통 귀결된다.

UITableView에서는 style를 plain으로 설정하게 된다면, Header가 상단에 고정되게 된다.

위 예시 처럼(검정색이 헤더)가 고정되게 된다.

하지만 UICollectionView에서는 어떻게 헤더를 고정할까?

UICollectionView 에서 Header 고정

1. 먼저 UICollectionView 구성한다.

class ViewController: UIViewController {
	let layout = UICollectionViewFlowLayout()
	lazy var collectionView: UICollectionView = {
		let view = UICollectionView(frame: .zero, collectionViewLayout: layout)
		view.delegate = self
		view.dataSource = self
		view.register(Cell.self, forCellWithReuseIdentifier: "cell")
		return view
	}()
	
	override func viewDidLoad() {
		super.viewDidLoad()
		layout.minimumInteritemSpacing = 10
		view.addSubview(collectionView)
		collectionView.snp.makeConstraints {
			$0.top.bottom.equalTo(view.safeAreaLayoutGuide)
			$0.trailing.leading.equalToSuperview()
		}
	}
}

class Cell: UICollectionViewCell {
	override init(frame: CGRect) {
		super.init(frame: frame)
		addSubview(label)
		label.snp.makeConstraints {
			$0.leading.centerY.equalToSuperview()
		}
	}
	
	required init?(coder: NSCoder) {
		fatalError("init(coder:) has not been implemented")
	}
	
	let label = UILabel()
}

2. 이후 UICollectionView의 delegate들을 설정해준다.

  1. UICollectionViewDataSource
  2. UICollectionViewDelegateFlowLayout
extension ViewController: UICollectionViewDataSource {
	func numberOfSections(in collectionView: UICollectionView) -> Int {
		4
	}
	
	func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
		20
	}
	
	func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
		let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! Cell
		cell.backgroundColor = .cyan
		return cell
	}
}

extension ViewController: UICollectionViewDelegateFlowLayout {
	func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
		CGSize(width: self.view.frame.width, height: 40)
	}
}

그러면 오른쪽 사진과 같이 Cyan 색으로 칠해진 CollectionView가 쭈르륵 나온다.

이제 Header를 더해보자.

simulator_screenshot_121C7B85-5127-4771-AB78-32790969E6CE.png

3. Header 더하기

  1. CollectionView에 헤더타입의 타입을 넣는다.
collectionView.register(Cell.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "header")
  1. 헤더가 어떤 것을 보여줄지 결정해야하니 UICollectionViewDataSource에 viewForSupplementaryElementOfKind를 추가한다.
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
	let cell = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "header", for: indexPath) as! Cell
	cell.label.text = "헤더는 상단에 고정 헤더는 상단에 고정 헤더는 상단에 고정 헤더는 상단에 고정 헤더는 상단에 고정 헤더는 상단에 고정 헤더는 상단에 고정 헤더는 상단에 고정"
	cell.label.textColor = .white
	cell.backgroundColor = .black
	return cell
}
  1. 헤더가 어떤 사이즈로 보여줘야할지 결정해야하니 UICollectionViewDelegateFlowLayoutreferenceSizeForHeaderInSection를 추가한다