#はじめに
今回はCollectionViewでheaderとfooterを扱う方法を紹介したいと思います。
以下のようなものを作ってみます。
#GitHub
以下のHeaderFooterCollectionView
に今回のリポジトリあります!
#実装
まず、真ん中の赤い正方形を作ります。
カスタムセルでXIBを作成してコードは以下のようにしてください。
final class MyCollectionViewCell: UICollectionViewCell {
static var toString: String {
return String(describing: self)
}
static let id = MyCollectionViewCell.toString
static func nib() -> UINib {
return UINib(nibName: MyCollectionViewCell.toString, bundle: nil)
}
func configure() {
backgroundColor = .red
}
}
そして、ViewController
のviewDidLoad
以下のように、UICollectionViewFlowLayout
を利用します。
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
layout.itemSize = CGSize(width: self.view.frame.size.width / 2.2,
height: self.view.frame.size.width / 2.2)
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView?.register(MyCollectionViewCell.nib(),
forCellWithReuseIdentifier: MyCollectionViewCell.id)
collectionView?.delegate = self
collectionView?.dataSource = self
collectionView?.backgroundColor = .white
view.addSubview(collectionView!)
}
collectionView
の縦横のサイズを決めます。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView?.frame = self.view.bounds
}
そして、delegateメソッドを以下のように書きます。
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MyCollectionViewCell.id, for: indexPath) as! MyCollectionViewCell
cell.configure()
return cell
}
}
これで真ん中に表示4つの赤い正方形が表示されたと思います。
次はheaderを作成していきます。
headerやfooterは以下のようなUICollectionReusableView
というものを使います。
final class HeaderCollectionReusableView: UICollectionReusableView {
static var toString: String {
return String(describing: self)
}
static let id = HeaderCollectionReusableView.toString
private let label: UILabel = {
let label = UILabel()
label.text = "header"
label.font = .systemFont(ofSize: 50)
label.textAlignment = .center
label.textColor = .white
return label
}()
func configure() {
backgroundColor = .green
addSubview(label)
}
override func layoutSubviews() {
super.layoutSubviews()
label.frame = bounds
}
}
そして、ViewControllerないで以下のように書いていきます。
cellを登録
collectionView?.register(HeaderCollectionReusableView.self,
forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
withReuseIdentifier: HeaderCollectionReusableView.id)
UICollectionViewDataSource
メソッド
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader,
withReuseIdentifier: HeaderCollectionReusableView.id,
for: indexPath) as! HeaderCollectionReusableView
header.configure()
return header
}
}
UICollectionViewDelegateFlowLayout
メソッド
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: view.frame.size.width, height: 200)
}
}
これで緑色のヘッダーがつかされたと思います。
青色のフッターも同じように作成します。
ただし、UICollectionViewDataSource
のdequeueReusableSupplementaryView
を以下のように変更します。
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
if kind == UICollectionView.elementKindSectionFooter {
let footer = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionFooter,
withReuseIdentifier: FooterCollectionReusableView.id,
for: indexPath) as! FooterCollectionReusableView
footer.configure()
return footer
} else {
let header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader,
withReuseIdentifier: HeaderCollectionReusableView.id,
for: indexPath) as! HeaderCollectionReusableView
header.configure()
return header
}
}
}
最後に、以下のようにUICollectionViewDelegate
のnumberOfSections
を追加すれば完成です。
extension ViewController: UICollectionViewDelegate {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 5
}
}
#解説
大切なところだけ解説します。
UICollectionReusableView
UICollectionReusableViewでカスタムヘッダーやフッターを作成します。
カスタムヘッダーの手順は以下の通りです。
1.カスタムヘッダーを用意する
2.viewDidLoadでカスタムヘッダーをregisterする
3.collectionView(viewForSupplementaryElementOfKind)
4.collectionView(referenceSizeForHeaderInSection)
viewForSupplementaryElementOfKind
ではヘッダーおよびフッターの設定をします。
referenceSizeForHeaderInSection
では名前の通り、ヘッダーのサイズを決めます。
#おわりに
CollectionViewも奥が深いですね、、、