无法将 viewForSupplementaryElementOfKind 出队 'the view returned was not retrieved'

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

我有一个包含 2 个部分的 collectionView。不过,我正在尝试 dequeueReusableSupplementaryView。我收到以下错误:

*** 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

这是我的代码:

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()
        }
    }
}

我已确保注册了所有单元格和补充视图。

注册单元格、页眉和页脚

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
}()

错误消息告诉您,您正在 return 浏览的视图要么 (a) 不是 return 由 dequeueReusableSupplementaryViewOfKind 编辑的;要么或 (b) 是 nil。根据错误消息判断,第二部分的 UICollectionElementKindSectionFooter 似乎有问题。

您在很多地方 returning UICollectionReusableView()。那是无效的,将导致此错误。您必须 return 一个实际的出队补充视图(或配置您的集合视图,以便 viewForSupplementaryElementOfKind 不会为该部分种类调用)。

如果不使用UICollectionViewController必须调用里面的寄存器init()

或者如果您在 UIViewController 中创建一个 collectionView,您必须将 collectionView 声明为 lazy var 而不是 let

示例

private let headerIdentifer = "Cell"
private let reuseIdentifer = "Header"

private lazy var collectionView: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.delegate = self
    cv.dataSource = self
    cv.register(CellView.self, forCellWithReuseIdentifier: reuseIdentifer)
    cv.register(HeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: headerIdentifer)
    cv.backgroundColor = .clear
    cv.showsVerticalScrollIndicator = false
    return cv
}()