Swift:如何为 collection 视图部分选择性地 return 一个 header?
Swift: How to Optionally return a header for a collection view section?
我有一个UICollectionViewDiffableDataSource
像这样:
var data:UICollectionViewDiffableDataSource<Section, Message>!
我这样定义部分 header 的布局:
let header = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: .init(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(10)),
elementKind: UICollectionView.elementKindSectionHeader,
alignment: .top
)
section.boundarySupplementaryItems = [header]
最后,对于 return 我的 header,我有这个功能 return 是 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
.
中看到我的 header
我想要什么:我如何有选择地决定不显示特定部分的特定header?
当我在以下函数中尝试 return 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))'
关于如何“可选地”return 一个 header 部分的唯一想法是注册另一个高度为零且 return 的 header 视图这个 header 当我根本不想 return 任何 header 时。
但对我来说,这似乎有点混乱,如果我可以 return nil
当我不显示 header.
我做错了什么?
感谢您的帮助!
有点丑陋的解决方案,但我创建了一个简单的空视图:
class EmptyHeader : UICollectionReusableView {
static var reuseIdentifier:String = "spacer"
}
然后,当我不想要 header 时,我只是 return 这个视图。 (确保先将视图注册到集合视图)。
我最近在看这个,我想出的解决方案是根据您使用 return nil
supplementaryViewProvider
关闭。
一些伪代码:
给定一些条件
let myCondition = ...
我的补充视图提供者:
dataSource.supplementaryViewProvider = { collectionView, kind, indexPath in
// ...
guard myCondition else { return nil }
}
并且在您的组合布局提供程序中 function/closure 您可以:
let section = NSCollectionLayoutSection(...)
if myCondition {
let header = NSCollectionLayoutBoundarySupplementaryItem(...)
section.boundarySupplementaryItems = [header]
}
这将允许您从 supplementaryViewProvider
闭包中 return nil
因为集合视图永远不会在该条件为 true
时请求补充视图(如果确实如此,您仍然会看到崩溃)。
这应该在为 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)
您的条件显然可以绑定到您的数据源和部分索引,因此您不会 运行 与动态创建的部分不同步。
我有一个UICollectionViewDiffableDataSource
像这样:
var data:UICollectionViewDiffableDataSource<Section, Message>!
我这样定义部分 header 的布局:
let header = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: .init(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(10)),
elementKind: UICollectionView.elementKindSectionHeader,
alignment: .top
)
section.boundarySupplementaryItems = [header]
最后,对于 return 我的 header,我有这个功能 return 是 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
.
我想要什么:我如何有选择地决定不显示特定部分的特定header?
当我在以下函数中尝试 return 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))'
关于如何“可选地”return 一个 header 部分的唯一想法是注册另一个高度为零且 return 的 header 视图这个 header 当我根本不想 return 任何 header 时。
但对我来说,这似乎有点混乱,如果我可以 return nil
当我不显示 header.
我做错了什么?
感谢您的帮助!
有点丑陋的解决方案,但我创建了一个简单的空视图:
class EmptyHeader : UICollectionReusableView {
static var reuseIdentifier:String = "spacer"
}
然后,当我不想要 header 时,我只是 return 这个视图。 (确保先将视图注册到集合视图)。
我最近在看这个,我想出的解决方案是根据您使用 return nil
supplementaryViewProvider
关闭。
一些伪代码:
给定一些条件
let myCondition = ...
我的补充视图提供者:
dataSource.supplementaryViewProvider = { collectionView, kind, indexPath in
// ...
guard myCondition else { return nil }
}
并且在您的组合布局提供程序中 function/closure 您可以:
let section = NSCollectionLayoutSection(...)
if myCondition {
let header = NSCollectionLayoutBoundarySupplementaryItem(...)
section.boundarySupplementaryItems = [header]
}
这将允许您从 supplementaryViewProvider
闭包中 return nil
因为集合视图永远不会在该条件为 true
时请求补充视图(如果确实如此,您仍然会看到崩溃)。
这应该在为 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)
您的条件显然可以绑定到您的数据源和部分索引,因此您不会 运行 与动态创建的部分不同步。