How do I add a section title in UICollectionView?

Solution 1:

To add the custom label above every section in UICollectionView, please follow below steps

  1. Enable the section header in UICollectionView

enter image description here

  1. Add a new file of type UICollectionReusableView
  2. In the storyboard change the class of section header in UICollectionViewCell to the newly added file of type UICollectionReusableView.
  3. Add a label in section header of UICollectionViewCell in storyboard
  4. Connect the label in the section header to the UICollectionReusableView file

    class SectionHeader: UICollectionReusableView {
        @IBOutlet weak var sectionHeaderlabel: UILabel!
    }
    
  5. In the ViewController add the below code

    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    
        if let sectionHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "SectionHeader", for: indexPath) as? SectionHeader{
            sectionHeader.sectionHeaderlabel.text = "Section \(indexPath.section)"
            return sectionHeader
        }
        return UICollectionReusableView()
    }
    

Here "SectionHeader" is name of the file added to type UICollectionReusableView

Solution 2:

Implement collectionView:viewForSupplementaryElementOfKind:atIndexPath: and supply a dequeued UICollectionElementKindSectionHeader containing your label. If this is a flow layout, be sure also to set the headerReferenceSize or you still won't see anything.

Solution 3:

If you want a programmatic solution in Swift 4.2, you can do the following:

  1. Setup the UICollectionViewDelegate and UICollectionViewDelegateFlowLayout

  2. Make custom UICollectionReusableView subclasses with whatever views you want defined. Here's one for a header, you can create another for a footer with different characteristics:

    class SectionHeader: UICollectionReusableView {
         var label: UILabel = {
             let label: UILabel = UILabel()
             label.textColor = .white
             label.font = UIFont.systemFont(ofSize: 16, weight: .semibold)
             label.sizeToFit()
             return label
         }()
    
         override init(frame: CGRect) {
             super.init(frame: frame)
    
             addSubview(label)
    
             label.translatesAutoresizingMaskIntoConstraints = false
             label.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
             label.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20).isActive = true
             label.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
  3. Implement the viewForSupplementaryElementOfKind method with the custom views:

    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { 
        if kind == UICollectionView.elementKindSectionHeader {
             let sectionHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "header", for: indexPath) as! SectionHeader
             sectionHeader.label.text = "TRENDING"
             return sectionHeader
        } else { //No footer in this case but can add option for that 
             return UICollectionReusableView()
        }
    }
    
  4. Implement the referenceSizeForHeaderInSection and referenceSizeForFooterInSection methods. Header method shown below for example:

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        return CGSize(width: collectionView.frame.width, height: 40)
    }