如何以编程方式启用/禁用 UICollectionView 中的部分标题?
Posted
技术标签:
【中文标题】如何以编程方式启用/禁用 UICollectionView 中的部分标题?【英文标题】:How can I enable/disable section headers in UICollectionView programmatically? 【发布时间】:2014-07-03 16:15:48 【问题描述】:在Storyboard(复选框)中可以轻松完成,但是在代码中执行呢?
【问题讨论】:
投反对票?我错过了什么吗? 【参考方案1】:您可以使用UICollectionViewDelegateFlowLayout
的collectionView:layout:referenceSizeForHeaderInSection:
方法并返回CGSizeMake(0,0)
或相应地设置UICollectionViewFlowLayout
的headerReferenceSize
。
编辑:
headerReferenceSize
实际上是故事板用来显示/隐藏标题的属性。我已经从 Storyboard 文件中添加了相关行
带有部分复选框打开:
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="xAt-Uo-bMl">
<size key="headerReferenceSize" /></collectionViewFlowLayout>
带部分复选框关闭
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="xAt-Uo-bMl">
<size key="headerReferenceSize" /></collectionViewFlowLayout>
编辑#2:
来自the official docs:
流布局中的每个部分都可以有自己的自定义页眉和页脚。要为视图配置页眉或页脚,您必须将页眉或页脚的大小配置为非零。您可以通过实现适当的委托方法或为 headerReferenceSize 和 footerReferenceSize 属性分配适当的值来做到这一点。如果页眉或页脚大小为 0,则对应的视图不会添加到集合视图中。
【讨论】:
我遇到的问题是我动态更改了页脚大小。我在 - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath 中更改了 footerReferenceSize 并通过 [self.collectionview performBatchUpdates:^ //更改 footerReferenceSize 的布局 完成:^(BOOL 完成) ];不工作,它仍然显示collectionViewLayout返回的初始值referenceSizeForFooterInSection:(NSInteger)section 令人惊讶的是它是情节提要中的复选框,但您在代码中设置了高度。这不适合我。哦,好吧,这解决了我的问题,即在 ViewDidLoad 之后的异步方法之前,我没有为 CollectionView 设置源。这在大多数 CollectionViews 中都可以正常工作,但是带有 SupplementaryViews 的不允许这样做,所以我从情节提要中禁用了它们,然后在设置源之后设置它们。【参考方案2】:只需将您不想显示的标题的高度更改为 0...
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
if (section == 0)
return CGSizeZero;
else
return CGSizeMake(collectionView.frame.size.width,50);
【讨论】:
该代码甚至无法编译——返回 50;不是尺寸。【参考方案3】:nil 和 [UIView new] 都不起作用,都会抛出相同的错误。最佳答案在How to change the UICollectionView footerview's height programatically
【讨论】:
【参考方案4】:我在此主题上找到的所有答案都假定您使用的是 UICollectionViewFlowLayout
或其子类,您可以在其中直接修改补充视图的大小。
我认为所有这些答案都有缺点,尤其是那些建议在布局子类中修改标题大小的答案,这会导致管理您的数据的任何对象与布局本身发生不必要的耦合。此外,您必须注意标题的约束,否则如果您将视图的大小设置为零,您将收到关于破坏约束的日志消息。
适用于每个 ios 版本的解决方案,无论您使用的是流式布局还是组合式布局。
只返回一个有效的空视图。
创建UICollectionReusableView
的子类
class EmptyCollectionReusableView: UICollectionReusableView
override func sizeThatFits(_ size: CGSize) -> CGSize
var size = super.sizeThatFits(size)
size.height = .leastNonzeroMagnitude
return size
在你的集合视图中注册它,就像你在普通的补充视图中一样
let identifier = "emptySupplementaryViewIdentifier"
collectionView.register(EmptyCollectionReusableView.self,
forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
withReuseIdentifier: identifier)
每当您想“隐藏”标题时,您就可以将其出列,就像使用普通补充视图一样:
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView
if shouldHideHeader
return collectionView.dequeueReusableSupplementaryView(ofKind: kind,
withReuseIdentifier: "emptySupplementaryViewIdentifier",
for: indexPath)
// Return your normal header
使用 Diffable 数据源时,将此代码插入您的数据源对象的supplementaryViewProvider
【讨论】:
【参考方案5】:当您根本不希望出现标题时,在委托的
viewForSupplementaryElementOfKind
return [UIView new];
时 kind == UICollectionElementKindSectionHeader:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
if (kind == UICollectionElementKindSectionHeader)
return [UIView new]; // Or even nil, I think it would work.
...
return /*something else that you want to return*/ ;
【讨论】:
谢谢。但是有没有办法完全禁用标题?就像在故事板设计器中一样?在设计器中禁用标头时实际发生的情况。 我认为这只是一个参考。如果我不想要标头,我总是通过不实现数据源/委托方法来管理它,或者如果我想要实现它们。我真的不认为您可以为此设置一个实际的公共属性。 如果你不想要任何部分,你甚至可以在方法 numberOfSectionsInCollectionView 中返回 0: 1.你不能返回nil
2。我确实实现了它,因为大多数时候我想要标题。直到我需要禁用它们。我想你的解决方案会做。但我仍然对最初的问题感到好奇。
返回[UIView new]
也不起作用。它发出一个错误。以上是关于如何以编程方式启用/禁用 UICollectionView 中的部分标题?的主要内容,如果未能解决你的问题,请参考以下文章
如何以编程方式启用/禁用网络接口? (Windows XP)
如何以编程方式启用/禁用 UICollectionView 中的部分标题?