UICollectionView and Supplementary View (header)

前端 未结 10 1094
南旧
南旧 2021-02-04 05:17

Trying to add a a Supplementary view into my UICollectionView as a header. I\'m having issues getting it to work.

I use a custom UICollectionViewFlowL

相关标签:
10条回答
  • 2021-02-04 05:25

    If you look at the error message, it says that the data source is not set. This should fix it:

    self.collectionView.dataSource = self;

    Make sure your view controller implements the data source protocol:

    YourViewController : UIViewController<UICollectionViewDataSource>

    0 讨论(0)
  • 2021-02-04 05:27

    I cleaned up my code and removed the UICollectionView I had created in IB and created it all in code. I ran the it again and got a different error and realized I didn't set the delegate or dataSource in IB. I did:

    self.collectionView.delegate = self;
    self.collectionView.datasource = self;
    

    But that must not have been good enough.

    So with UICollectionView created in IB and not setting the delgate/datasource in IB, but rather in the code:

    [self.view bringSubviewToFront:self.collectionView];
    self.collectionView.collectionViewLayout = collectionViewFlowLayout;
    self.collectionView.backgroundColor = [UIColor orangeColor];
    self.collectionView.delegate = self;
    self.collectionView.dataSource = self;
    
    [self.collectionView registerClass:[DatasetCell class] forCellWithReuseIdentifier:@"cvCell"];
    
    [self.collectionView registerClass:[CollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];
    

    was an issue. I redid it to create the UICollectionView all in code:

    UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:collectionViewFlowLayout];
    collectionView.translatesAutoresizingMaskIntoConstraints = FALSE;
    collectionView.backgroundColor = [UIColor yellowColor];
    collectionView.delegate = self;
    collectionView.dataSource = self;
    
    [collectionView registerClass:[DatasetCell class] forCellWithReuseIdentifier:@"cvCell"];
    
    [collectionView registerClass:[CollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];
    
    [self.view addSubview:collectionView];
    
    self.collectionView = collectionView;
    

    and i get a different error:

    *** Assertion failure in -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2380.17/UICollectionView.m:2249
    *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of kind: UICollectionElementKindSectionHeader with identifier CollectionHeaderView - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
    

    which I'll try to figure out.

    EDIT:

    figured it out, I was registering the header incorrectly:

    [collectionView registerClass:[CollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];
    

    switched to:

    UINib *headerNib = [UINib nibWithNibName:@"CollectionHeaderView" bundle:nil];
    
    [collectionView registerNib:headerNib forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];
    

    and everything works. Not entirely sure how the registerClass: wasn't working though.

    0 讨论(0)
  • 2021-02-04 05:35

    I faced with the similar problem, but my app crashed after I programmatically pop my UICollectionViewController. In some reason (I think it's just a bug in SDK) self.collectionView was alive after its' controller destroy, thus causing this failure:

    *** Assertion failure in -[UICollectionView _createPreparedSupplementaryViewForElementOfKind:atIndexPath:withLayoutAttributes:applyAttributes:], /SourceCache/UIKit/UIKit-2935.137/UICollectionView.m:1305
    *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView dataSource is not set'
    

    The solution is just override -dealloc in UICollectionViewController and release self.collectionView manually. ARC code:

    - (void)dealloc {
    
        self.collectionView = nil;
    }
    

    Hope this will save time for somebody.

    0 讨论(0)
  • 2021-02-04 05:35

    I was having the same issue and similarly, I was not registering the header correctly. there are several threads on here that all suggest using a Nib to define the header but I have done it differently and is working fine.

    I have a custom header SizeCollectionHeader, which inherits the UICollectionReusableView. It is registered like this.

        [self.collectionView registerClass:[GRSizeCollectionHeader class] forSupplementaryViewOfKind:@"UICollectionElementKindSectionHeader"
                                                                                 withReuseIdentifier:@"SupplementaryViewIdentifier"];
    

    and is working fine.

    my initial problem was that had a random "Kind" value like this.

        [self.collectionView registerClass:[GRSizeCollectionHeader class] forSupplementaryViewOfKind:@"SupplementaryViewKind"
                                                                                 withReuseIdentifier:@"SupplementaryViewIdentifier"];
    

    This will crash.

    So I just wanted to comment for anybody that is looking here that you don't need to use a nib.

    0 讨论(0)
  • 2021-02-04 05:41

    This answer is similar to the others where you create a method that checks for the data source, but it's a bit simpler. It seems the issue is related to the collection view's layout sticking around after the collection has been released. So I zeroed out the layout's properties as below and the error disappeared.

    deinit {
        let layout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
        layout.estimatedItemSize = CGSizeZero
        layout.sectionInset = UIEdgeInsetsZero
        layout.headerReferenceSize = CGSizeZero
    }
    
    0 讨论(0)
  • 2021-02-04 05:41

    I kept getting the same error. I had set up the CustomHeaderView for my collectionView. I had class of the Collection Reusable View to my CustomHeaderView and i had set the identifier. I 1/2 an hour trying to figure out why this was failing.

    Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of kind: UICollectionElementKindSectionFooter with identifier SectionHeader - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

    You need to read the logs carefully...lesson learned.

    'could not dequeue a view of kind: UICollectionElementKindSectionFooter

    The reason is because In storyboard - in the collectionView Identity Inspector I had checked both Accessories: Section Header and Section Footer. I only needed section header. Simply uncheck footer...build and run..BOOM!

    0 讨论(0)
提交回复
热议问题