Swift:如何选择返回集合视图部分的标题?
Posted
技术标签:
【中文标题】Swift:如何选择返回集合视图部分的标题?【英文标题】:Swift: How to Optionally return a header for a collection view section? 【发布时间】:2021-01-09 00:57:52 【问题描述】:我有一个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
会更干净。
我做错了什么?
感谢您的帮助!
【问题讨论】:
【参考方案1】:这应该在为 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)
您的条件显然可以绑定到您的数据源和部分索引,因此您不会与动态创建的部分不同步。
【讨论】:
【参考方案2】:我最近正在研究这个问题,我想出的解决方案是根据在 supplementaryViewProvider
闭包上返回 nil
所使用的相同条件,选择性地设置组合布局 boundarySupplementaryItems
。
一些伪代码:
给定条件
let myCondition = ...
我的补充视图提供者:
dataSource.supplementaryViewProvider = collectionView, kind, indexPath in
// ...
guard myCondition else return nil
在您的组合布局提供程序函数/闭包中,您可以:
let section = NSCollectionLayoutSection(...)
if myCondition
let header = NSCollectionLayoutBoundarySupplementaryItem(...)
section.boundarySupplementaryItems = [header]
这将允许您从 supplementaryViewProvider
闭包返回 nil
,因为当条件为 true
时,集合视图永远不会请求补充视图(如果这样做,您仍然会看到崩溃)。
【讨论】:
【参考方案3】:有点丑陋的解决方案,但我创建了一个简单的空视图:
class EmptyHeader : UICollectionReusableView
static var reuseIdentifier:String = "spacer"
然后,当我不想要标题时,我只返回此视图。 (确保先将视图注册到collectionview)。
【讨论】:
以上是关于Swift:如何选择返回集合视图部分的标题?的主要内容,如果未能解决你的问题,请参考以下文章