Swift:如何选择性地返回集合视图部分的标题?

问题描述

我有一个UICollectionViewDiffableDataSource这样的:

var data:UICollectionViewDiffableDataSource<Section,Message>!

我像这样定义我的部分标题的布局:

let header = NSCollectionLayoutBoundarySupplementaryItem(
    layoutSize: .init(widthDimension: .fractionalWidth(1.0),heightDimension: .estimated(10)),elementKind: UICollectionView.elementKindSectionHeader,alignment: .top
)
section.boundarySupplementaryItems = [header]

最后,为了返回我的标题我有一个返回 UICollectionReusableView函数,如下所示:

func setupHeaderData() {
    data.supplementaryViewProvider = { collectionView,kind,indexPath in
        return DateStampBuilder(data: self.data,style: self.style).build(collectionView: collectionView,kind: kind,indexPath: indexPath)
    }
}

有什么好处:我可以在 UICollectionView 中看到我的标题

我想要什么:我如何选择不显示特定部分的特定标题

当我尝试在以下函数中返回 nil 时:

data.supplementaryViewProvider = { collectionView,indexPath in

我收到以下错误

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

我对如何“可选”返回一个部分的标题的唯一想法是注册一个高度为零的标题视图,并在我根本不想返回任何标题时返回此标题

但对我来说,这似乎有点混乱,如果我不显示标题时可以直接返回 nil 会更简洁。

我做错了什么?


感谢您的帮助!

解决方法

这应该在为 collectionView 创建布局时完成。以下是如何使用 UICollectionLayoutListConfiguration 执行此操作的示例:

let sectionProvider = { [weak self] (sectionIndex: Int,layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
        var section: NSCollectionLayoutSection
        
        var listConfiguration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
        
        if condition {
            listConfiguration.headerMode = .supplementary
        } else {
            listConfiguration.headerMode = .none
        }
        
        section = NSCollectionLayoutSection.list(using: listConfiguration,layoutEnvironment: layoutEnvironment)
        return section
    }
    
let layout = UICollectionViewCompositionalLayout(sectionProvider: sectionProvider)
    
collectionView.setCollectionViewLayout(layout,animated: true)

您的条件显然可以绑定到您的数据源和部分索引,因此您不会与动态创建的部分失去同步。

,

有点丑陋的解决方案,但我创建了一个简单的空视图:

class EmptyHeader : UICollectionReusableView {    
    static var reuseIdentifier:String = "spacer"
}

然后,当我不想要标题时,我只返回此视图。 (确保先向 collectionview 注册视图)。