【问题标题】:UICollectionView & custom UICollectionReusableView not worksUICollectionView 和自定义 UICollectionReusableView 不起作用
【发布时间】:2013-05-10 21:24:42
【问题描述】:

我正在尝试在我的 UICollectionView 标头中使用自定义 UICollectionReusableView(具有自己的类和 XIB)。但是在标题的位置获取数据后,我什么都没有。

我的步骤:

  1. viewDidLoad中注册类:

     [self.collectionView registerClass:[CollectionViewHeader class] 
      forSupplementaryViewOfKind: UICollectionElementKindSectionHeader 
      withReuseIdentifier:@"HeaderView"];
    
  2. 试图显示:

    - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
    {
    UICollectionReusableView *reusableView = nil;
    
    if (kind == UICollectionElementKindSectionHeader) {
        CollectionViewHeader *collectionHeader = [self.collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];
    
        NSInteger section = [indexPath section];
        id <NSFetchedResultsSectionInfo> sectionInfo = [fetchRecipes sections][section];
        collectionHeader.headerLabel.text = @"bla-bla-bla";
    
        reusableView = collectionHeader;
    }
    
    return reusableView;
    }
    

谁能告诉我怎么了? ) 感谢您的任何建议

【问题讨论】:

    标签: ios xib uicollectionview uicollectionreusableview


    【解决方案1】:

    我认为您正在向 xib 添加标签。所以你需要 registerNib: 来代替 registerClass:

    【讨论】:

      【解决方案2】:
      1. 在 viewDidLoad 部分注册您的标题 nib/xib。

        [self.collectionView registerNib:  [UINib nibWithNibName:@"headerCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"headerCell"]; 
        
      2. 创建自定义补充视图单元。

        - (headerCollectionViewCell *)collectionView:(UICollectionView *)collectionViews viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
        {
            UICollectionReusableView *reusableView = nil;
        
            if (kind == UICollectionElementKindSectionHeader) {
        
                UINib *nib = [UINib nibWithNibName:@"headerCollectionViewCell" bundle:nil];
        
                [collectionViews registerNib:nib forCellWithReuseIdentifier:@"headerCell"];
        
                headerCollectionViewCell *collectionHeader = [collectionViews dequeueReusableCellWithReuseIdentifier:@"headerCell" forIndexPath:indexPath];
                collectionHeader.titleLabel.text = @"What";
        
                reusableView = collectionHeader;
           }
        
           return reusableView;
        }
        

      【讨论】:

      • 您使用的是registerNib:forCellWithReuseIdentifier:。你应该使用registerNib:forSupplementaryViewOfKind:withReuseIdentifier:
      • 对网格项目使用单元格,对页眉/页脚使用补充视图。更多here。此外,this post 有点旧,但它有一些很好的图表和 UICollectionView 不同元素的语义使用示例。希望这能澄清一点。
      • 并且将其添加到 viewDidLoad 您不必在委托函数中再次添加它。 10x @gabriel-osorio 你是对的。
      • 请安德鲁编辑你的答案,没有加布里埃尔的评论是没用的。
      • UICollectionView [self.selectionCollectionView registerNib:[UINib nibWithNibName:@"FlootThumbnailCollectionReusableView" bundle:nil] forCellWithReuseIdentifier:@"HeaderView"];的页眉和页脚视图请使用下面的代码
      【解决方案3】:

      以防万一有人需要解决方案。 您不必使用

      注册头类
      [self.collectionView registerClass:...]
      

      只需使用布局的委托方法返回头类即可。

      【讨论】:

        【解决方案4】:

        其实有几个原因:

        1. (最常见) 如果你在故事板中添加你的suplementaryView,然后尝试注册类

          [self.stickyCollectionView registerClass:[<CLASSFORSUPPLEMENTARYVIEWW> class]
                    forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
                           withReuseIdentifier:NSStringFromClass([<CLASSFORSUPPLEMENTARYVIEWW> class])];
          

        你会得到suplementaryView,但不是你创建的(标准的)——你会看到obj,但实际上这就像占位符。

        例子:

        在这里你可以看到创建了 obj,但是 outlet 是 nil(在这个简单的例子中只有一个 outlet - _monthNameLabel)。

        1. 我也看到过几次这个问题

        如果您创建单独的Obj 来处理collectionView 的dataSourse/delegate 并为其添加引用出口,并且在init 方法中尝试将类注册到您的出口(假设在单独的nib 文件中创建的视图),你也将收到与以前相同的结果,但原因是另一个 - 你的出口在这里为零:

        例如,作为解决方案,您可以为此使用自定义设置器:

        #pragma mark - CustomAccessors
        
        - (void)setcCollectionView:(UICollectionView *)collectionView
        {
            _collectionView = collectionView;
        
            [self.stickyCollectionView registerNib:...];
        }
        
        1. @Anil Varghese 建议

        你可以用registerClass代替registerNib

        【讨论】:

          【解决方案5】:

          Xcode 9、Swift 4:

          viewDidLoad注册UICollectionReusableView

          self.collectionView.register(UINib(nibName: "DashBoardCollectionReusableView", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "ReuseIdentifier")
          

          【讨论】:

            【解决方案6】:
            class CustomFlowLayout: UICollectionViewFlowLayout {
            
                override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
                    let attributesForElementsInRect = super.layoutAttributesForElements(in: rect)
                    var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]()
            
                    for attributes in attributesForElementsInRect! {
            
                        if !(attributes.representedElementKind == UICollectionElementKindSectionHeader
                            || attributes.representedElementKind == UICollectionElementKindSectionFooter) {
            
                            // cells will be customise here, but Header and Footer will have layout without changes.
                        }
            
                        newAttributesForElementsInRect.append(attributes)
                    }
            
                    return newAttributesForElementsInRect
                }
            }
            
            
            class YourViewController: UIViewController {
            
                override func viewDidLoad() {
                    super.viewDidLoad()
            
                    let headerNib = UINib.init(nibName: "HeaderCell", bundle: nil)
                    collectionView.register(headerNib, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "HeaderCell")
            
                    let footerNib = UINib.init(nibName: "FooterCell", bundle: nil)
                    collectionView.register(footerNib, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "FooterCell")
                }
            
            
                func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
            
                    switch kind {
                    case UICollectionElementKindSectionHeader:
                        let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "HeaderCell", for: indexPath) as! HeaderCell
                        return headerView
                    case UICollectionElementKindSectionFooter:
                        let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "FooterCell", for: indexPath) as! FooterCell
                        return footerView
                    default:
                        return UICollectionReusableView()
                    }
                }
            
                func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
                    return CGSize(width: collectionView.frame.width, height: 45)
                }
            
                func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
                    return CGSize(width: collectionView.frame.width, height: 25)
                }
            }
            

            【讨论】:

              【解决方案7】:

              您正确地注册了该类并且代理已正确实现。

              问题可能是没有为header view配置流布局(默认),你的代码或界面文件中有这行吗?

              UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)_collectionView.collectionViewLayout;
              flowLayout.headerReferenceSize = CGSizeMake(CGRectGetWidth(_collectionView.bounds), 100);
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2016-09-18
                • 1970-01-01
                • 2014-01-21
                • 1970-01-01
                • 1970-01-01
                • 2021-09-23
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多