UICollectionView:如何获取节的标题视图?

Dor*_*Roy 29 iphone ios uicollectionview

有一种通过indexPath(UICollectionView cellForItemAtIndexPath:)获取单元格的方法.但是,在创建之后,我找不到一种方法来获得一个补充视图,如页眉或页脚.任何想法?

rob*_*off 42

UPDATE

从iOS 9开始,您可以使用-[UICollectionView supplementaryViewForElementKind:atIndexPath:]索引路径获取补充视图.

原版的

最好的办法是将自己的字典映射到补充视图的索引路径.在您的collectionView:viewForSupplementaryElementOfKind:atIndexPath:方法中,在返回之前将视图放入字典中.在您的collectionView:didEndDisplayingSupplementaryView:forElementOfKind:atIndexPath:,从字典中删除视图.

  • 是否有充分的理由说UICollectionView不为此提供API? (13认同)
  • iOS 9引入了`func supplementViewForElementKind(elementKind:String,atIndexPath indexPath:NSIndexPath) - > UICollectionReusableView` :) (11认同)

小智 28

我想分享一下我对rob mayoff提供的解决方案的见解,但我不能发表评论,所以我把它放在这里:

对于每一个试图保持集合视图使用的补充视图的参考,但由于过早地遇到松散轨道问题的人

collectionView:didEndDisplayingSupplementaryView:forElementOfKind:atIndexPath:
Run Code Online (Sandbox Code Playgroud)

被调用太多次,尝试使用NSMapTable而不是字典.

我用

@property (nonatomic, strong, readonly) NSMapTable *visibleCollectionReusableHeaderViews;
Run Code Online (Sandbox Code Playgroud)

像这样创建:

_visibleCollectionReusableHeaderViews = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory valueOptions:NSMapTableWeakMemory];
Run Code Online (Sandbox Code Playgroud)

所以当你保持对补充观点的引用时:

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    // ( ... )
    [_visibleCollectionReusableHeaderViews setObject:cell forKey:indexPath];
Run Code Online (Sandbox Code Playgroud)

它在NSMapTable中只保留了对它的WEAK引用,并且它保持足够长,因为对象没有被释放!

您不再需要从中删除视图

collectionView:didEndDisplayingSupplementaryView:forElementOfKind:atIndexPath:
Run Code Online (Sandbox Code Playgroud)

因为一旦取消分配视图,NSMapTable将丢失该条目.


Ale*_*lex 9

您要做的第一件事是在集合视图的属性检查器中选中"Section Header"框.然后添加一个集合可重用视图,就像将单元格添加到集合视图中一样,编写标识符并根据需要为其创建类.然后实现方法:

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
Run Code Online (Sandbox Code Playgroud)

从那里开始就像你使用cellForItemAtIndexPath一样,指定它是否是你编码的页眉或页脚也很重要:

if([kind isEqualToString:UICollectionElementKindSectionHeader])
{
    Header *header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"headerTitle" forIndexPath:indexPath];
    //modify your header
    return header;
}

else
{

    EntrySelectionFooter *footer = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"entryFooter" forIndexPath:indexPath];
    //modify your footer
    return footer;
}
Run Code Online (Sandbox Code Playgroud)

使用indexpath.section知道它在哪个部分也注意到Header和EntrySelectionFooter是我制作的UICollectionReusableView的自定义子类

  • `kind`是一个`NSString`.它应该使用`if([kind isEqualToString:UICollectionElementKindSectionHeader])`而不是`==`进行比较. (3认同)