1

我有一个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, kind, 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在我不显示标题时返回,那会更干净。

我究竟做错了什么?


谢谢你的帮助!

4

3 回答 3

7

这应该在为 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)

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

于 2021-01-28T11:01:03.660 回答
2

我最近在看这个,我想出的解决方案是boundarySupplementaryItems根据你用来返回闭包nil的相同条件选择性地设置组合布局。supplementaryViewProvider

一些伪代码:

给定一些条件

let myCondition = ...

我的补充视图提供者:

dataSource.supplementaryViewProvider = { collectionView, kind, indexPath in 
    // ...
    guard myCondition else { return nil }
}

在您的组合布局提供程序功能/闭包中,您可以:

let section = NSCollectionLayoutSection(...)
if myCondition {
    let header = NSCollectionLayoutBoundarySupplementaryItem(...)
    section.boundarySupplementaryItems = [header]
}

nil这将允许您从闭包中返回,supplementaryViewProvider因为集合视图永远不会在该条件下请求补充视图true(如果确实如此,您仍然会看到崩溃)。

于 2021-01-13T00:12:19.147 回答
0

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

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

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

于 2021-01-10T23:48:19.283 回答