iosswiftuicollectionviewuicollectionreusableview

Unable to Dequeue viewForSupplementaryElementOfKind 'the view returned was not retrieved'


I have a collectionView with 2 sections. I am trying to dequeueReusableSupplementaryView however. I am getting the following error:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'the view returned from -collectionView:viewForSupplementaryElementOfKind:atIndexPath (UICollectionElementKindSectionFooter, {length = 2, path = 1 - 0}) was not retrieved by calling -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath: or is nil

Here is my code:

enum HomeSection: Int, CaseIterable {
    case companies = 0, reviews
}

private var sections = [HomeSection]()

override func viewDidLoad() {
        super.viewDidLoad()
        sections = [.companies, .reviews]
        setUpView()
    }

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let companyCell = collectionView.dequeueReusableCell(withReuseIdentifier: Identifier.companyCell, for: indexPath) as! CompanyCell
        let reviewCell = collectionView.dequeueReusableCell(withReuseIdentifier: Identifier.reviewCell, for: indexPath) as! ReviewCell
        switch sections[indexPath.section] {
        case .companies:
            let company = self.companies[indexPath.item]
            companyCell.company = company
            return companyCell
        case .reviews:
            let review = self.reviews[indexPath.item]
            reviewCell.review = review
            return reviewCell
        }
    }

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    switch sections[indexPath.section] {
    case .companies:
        switch kind {
        case UICollectionView.elementKindSectionHeader:
            let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: Identifier.headerView, for: indexPath) as! HeaderView
            return headerView
        case UICollectionView.elementKindSectionFooter:
            let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: Identifier.footerView, for: indexPath) as! FooterView
            return footerView
        default:
            return UICollectionReusableView()
        }
    case .reviews:
        switch kind {
        case UICollectionView.elementKindSectionHeader:
            return UICollectionReusableView()
        case UICollectionView.elementKindSectionFooter:
            return UICollectionReusableView()
        default:
            return UICollectionReusableView()
        }
    }
}

I have ensured I have all my cells and supplementaryViews registered.

Registered Cells, Headers & Footers

private let collectionView: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    layout.sectionHeadersPinToVisibleBounds = true
    let view = UICollectionView(frame: .zero, collectionViewLayout: layout)
    view.translatesAutoresizingMaskIntoConstraints = false
    view.backgroundColor = .white
    view.alwaysBounceVertical = true
    view.register(CompanyCell.self,
                  forCellWithReuseIdentifier: Identifier.companyCell)
    view.register(ReviewCell.self,
                  forCellWithReuseIdentifier: Identifier.reviewCell)
    view.register(HeaderView.self,
                  forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
                  withReuseIdentifier: Identifier.headerView)
    view.register(FooterView.self,
                  forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter,
                  withReuseIdentifier: Identifier.footerView)
    return view
}()

Solution

  • The error message is telling you that you are returning a view that was either (a) not returned by dequeueReusableSupplementaryViewOfKind; or (b) is nil. Judging on the error message, it would appear to be having a problem with the UICollectionElementKindSectionFooter for the second section.

    You are returning UICollectionReusableView() in quite a few places. That is not valid and will result in this error. You have to return an actual dequeued supplementary view (or configure your collection view so that viewForSupplementaryElementOfKind won’t be called for that section kind).