I wish to add a label to my UICollectionView programmatically, and have used the viewForSupplementaryElementOfKind and referenceSizeForHeaderInSection to set it up, however for some reason when I setup my views it is still placing it inside the first row of my CollectionView instead of the created header. As you can see in this screenshot, "Today" is in the first cell, instead of the header I created for it
class TvController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
private let cellId = "cellId"
private let headerId = "headerId"
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "TV"
navigationController?.navigationBar.isTranslucent = false
collectionView?.backgroundColor = .white
collectionView?.register(TvCell.self, forCellWithReuseIdentifier: cellId)
collectionView?.register(Header.self, forCellWithReuseIdentifier: headerId)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath)
return cell
}
//Row for each TV show
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 120)
}
//Today's date header
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let header = collectionView.dequeueReusableCell(withReuseIdentifier: headerId, for: indexPath) as! Header
return header
}
//Today's date header
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: view.frame.width, height: 60)
}
}
Here is the Header class
class Header: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupHeaderViews()
}
let dateLabel: UILabel = {
let title = UILabel()
title.text = "Today"
title.textColor = .gray
title.backgroundColor = .black
title.font = UIFont(name: "Montserrat", size: 17)
title.translatesAutoresizingMaskIntoConstraints = false
return title
}()
func setupHeaderViews() {
addSubview(dateLabel)
dateLabel.leftAnchor.constraint(equalTo: leftAnchor, constant: 20).isActive = true
dateLabel.topAnchor.constraint(equalTo: topAnchor, constant: 10).isActive = true
dateLabel.widthAnchor.constraint(equalToConstant: 120).isActive = true
dateLabel.heightAnchor.constraint(equalToConstant: 30).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
You're using the wrong method to register your header. You're also dequeuing using the wrong method. Since you're registering your header as a forSupplementaryViewOfKind -- You have to use deque the header using 'dequeueReusableSupplementaryView' method instead of 'dequeueReusableCell'
override func viewDidLoad() {
collectionView?.register(Header.self, forSupplementaryViewOfKind:
UICollectionElementKindSectionHeader, withReuseIdentifier: headerId)
}
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind:
String, at indexPath: IndexPath) -> UICollectionReusableView {
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier:
headerId, for: indexPath) as! Header
return header
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With