UICollectionView&自定义UICollectionReusableView不起作用

时间:2013-05-16 05:41:22

标签: ios xib uicollectionview uicollectionreusableview

我正在尝试在UICollectionReusableView标头中使用自定义UICollectionView(具有自己的类和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;
    }
    
  3. 谁能告诉我什么是错的? ) 感谢您的任何建议

7 个答案:

答案 0 :(得分:12)

我认为你正在为xib添加标签。因此,您需要 registerNib:作为标题视图,而不是 registerClass:

答案 1 :(得分:10)

  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;
    }
    

答案 2 :(得分:1)

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

注册标题类
[self.collectionView registerClass:...]

只需使用布局的委托方法返回标题类。

答案 3 :(得分:1)

实际上有几个原因:

  1. (最常见) 如果您在故事板中添加u&#39; r suplementaryView,然后尝试注册类

    [self.stickyCollectionView registerClass:[<CLASSFORSUPPLEMENTARYVIEWW> class]
              forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
                     withReuseIdentifier:NSStringFromClass([<CLASSFORSUPPLEMENTARYVIEWW> class])];
    
  2. 你会得到suplementaryView,但不是你创造(标准的) - 你会看到obj,但实际上这就像占位符一样。

    示例:

    enter image description here

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

    1. 我也几次看到这个问题
    2. 如果您为Obj处理dataSourse / delegate创建了单独的collectionView并为其添加了参考出口,并且在init方法中尝试将课程注册到u&#39; r outlet(假设在单独的nib文件中创建的视图),你也会收到与之前相同的结果,但是另一个原因 - 你的出口在这里是零:

      enter image description here

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

      #pragma mark - CustomAccessors
      
      - (void)setcCollectionView:(UICollectionView *)collectionView
      {
          _collectionView = collectionView;
      
          [self.stickyCollectionView registerNib:...];
      }
      
      1. 正如@Anil Varghese所建议的
      2. 您可以使用registerClass代替registerNib

答案 4 :(得分:1)

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)
    }
}

答案 5 :(得分:0)

Xcode 9,Swift 4:

UICollectionReusableView

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

答案 6 :(得分:0)

您正在正确注册该类,并且该委托已正确实现。

问题可能是未为标题视图配置流布局(默认情况下),代码或接口文件中是否包含此行?

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