【问题标题】:UICollectionView: How to get the header view for a section?UICollectionView:如何获取部分的标题视图?
【发布时间】:2012-11-15 09:06:29
【问题描述】:

有一种方法可以通过indexPath (UICollectionView cellForItemAtIndexPath:) 获取单元格。但我找不到一种方法来获取一个补充视图,如页眉或页脚,在创建后。有什么想法吗?

【问题讨论】:

    标签: iphone ios uicollectionview


    【解决方案1】:

    更新

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

    原创

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

    【讨论】:

    • 感谢您向我指出 didEndDisplayingSupplementaryView 方法!我错过了那个。
    • UICollectionView 没有为此提供 API 是否有充分的理由?
    • 我很确定苹果会重构 UICollectionView 的东西,让它比 UITableView 更相似,但仍然缺少很多功能
    • iOS 9 引入func supplementaryViewForElementKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView :)
    • 还添加了 iOS 9 public func visibleSupplementaryViewsOfKind(elementKind: String) -> [UICollectionReusableView]
    【解决方案2】:

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

    对于每一位试图保持对集合视图正在使用的补充视图的引用,但由于

    而遇到过早丢失跟踪问题的每一个人
    collectionView:didEndDisplayingSupplementaryView:forElementOfKind:atIndexPath:
    

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

    我用

    @property (nonatomic, strong, readonly) NSMapTable *visibleCollectionReusableHeaderViews;
    

    这样创建:

    _visibleCollectionReusableHeaderViews = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory valueOptions:NSMapTableWeakMemory];
    

    这样当您保留对补充视图的引用时:

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

    它在 NSMapTable 中只保留一个对它的 WEAK 引用,并且只要对象未被释放,它就会一直保留它!

    您不再需要从中删除视图

    collectionView:didEndDisplayingSupplementaryView:forElementOfKind:atIndexPath:
    

    因为一旦视图被释放,NSMapTable 就会丢失条目。

    【讨论】:

    • 感谢您提出这个好主意。它引导我使用 NSHashTable,它允许我保持对标题视图的弱引用,而无需在表中移动部分时保持键同步。
    • @DavidU 如果您没有密钥,如何找到您需要的补充视图?还是您有其他识别方式?
    • @DavidU 我最终覆盖了-applyLayoutAttributes 并获取了索引路径的副本,然后遍历哈希表中的视图并与索引路径进行比较。
    • @ZevEisenberg 我给每个标题一个唯一的标签,然后在 headerWithTag 方法中枚举它们。
    • @DavidU 很酷,听起来我们有类似的方法。另外:collection view 真的应该有这个 API:\
    【解决方案3】:

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

    - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
    

    从那里开始就像你对 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;
    }
    

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

    【讨论】:

    • kind 是一个NSString。应该使用if ([kind isEqualToString:UICollectionElementKindSectionHeader]) 进行比较,而不是==
    【解决方案4】:

    这种方法通常足以达到重新加载屏幕补充视图的目的:

    collectionView.visibleSupplementaryViews(ofKind: UICollectionElementKindSectionHeader)
    

    【讨论】:

    • Swift 4: collectionView.visibleSupplementaryViews(ofKind: UICollectionView.elementKindSectionHeader)
    猜你喜欢
    • 1970-01-01
    • 2015-11-07
    • 2014-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-21
    • 2015-07-12
    • 2016-09-19
    相关资源
    最近更新 更多