Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add UICollectionView Header

Tags:

ios

swift

iphone

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")
}
}
like image 903
unicorn_surprise Avatar asked Nov 09 '17 03:11

unicorn_surprise


1 Answers

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
}
like image 112
antdwash Avatar answered Oct 03 '22 06:10

antdwash