1

Currently I have a header cell in my UICollectionView. When I try to scroll UICollectionView, header cell will scroll together with UICollectionView list. May I know how to set the header cell stick on top? Please help. Thank you.

My current result:- enter image description here

My expected result:- enter image description here

Here is my sample code for header cell in my ViewController:-

- (UICollectionView *)collectionView
{
    if (!_collectionView) {
        DCHoverFlowLayout *layout = [DCHoverFlowLayout new];
        _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
        _collectionView.frame = CGRectMake(0, DCTopNavH, ScreenW, ScreenH - DCTopNavH);

        _collectionView.showsVerticalScrollIndicator = NO;
        _collectionView.delegate = self;
        _collectionView.dataSource = self;

        [_collectionView registerClass:[Product_HeadView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:Product_HeadViewID];

    }
    return _collectionView;
}



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

    UICollectionReusableView *reusableview = nil;
    if (kind == UICollectionElementKindSectionHeader){

        Product_HeadView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:Product_HeadViewID forIndexPath:indexPath];
        WEAKSELF

  };
        reusableview = headerView;
        return cell;
    }

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{

    _lastContentOffset = scrollView.contentOffset.y;

}
-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{

    if(scrollView.contentOffset.y > _lastContentOffset){
        [self.navigationController setNavigationBarHidden:YES animated:YES];
        self.collectionView.frame = CGRectMake(0, 20, ScreenW, ScreenH - 20);

        self.view.backgroundColor = [UIColor whiteColor];
    }else{
        [self.navigationController setNavigationBarHidden:NO animated:YES];
        self.collectionView.frame = CGRectMake(0, DCTopNavH, ScreenW, ScreenH - DCTopNavH);

        self.view.backgroundColor = ThemeBackgroundColor;
    }
}

#pragma mark - <UIScrollViewDelegate>
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    //Detect Button Visible
    _backTopButton.hidden = (scrollView.contentOffset.y > ScreenH) ? NO : YES;


    WEAKSELF
    [UIView animateWithDuration:0.25 animations:^{
        __strong typeof(weakSelf)strongSelf = weakSelf;
        strongSelf.footprintButton.dc_y = (strongSelf.backTopButton.hidden == YES) ? ScreenH - 60 : ScreenH - 110;
    }];

}

UPDATED:-

After applied Ted's code, here is the result and apps will crash. enter image description here

Gaurav Patel
  • 532
  • 1
  • 5
  • 19
Test 87
  • 101
  • 2
  • 10

3 Answers3

5

Swift version of tedd's answer:

let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.sectionHeadersPinToVisibleBounds = true
Vladislav Kovalyov
  • 763
  • 10
  • 24
  • Wow this kind of resolved my issue on iOS 12. iOS 13 was working well already. So random Apple, so random. – Guven Feb 13 '20 at 11:18
2

In your viewForSupplementaryElementOfKind method. Add these line:

UICollectionViewFlowLayout *layout = collectionView.collectionViewLayout;
layout.sectionHeadersPinToVisibleBounds = YES;
tedd
  • 65
  • 7
  • Hi Ted, I hit this error when applied your code :- Incompatible pointer types initializing 'UICollectionViewFlowLayout *' with an expression of type 'UICollectionViewLayout *'. Any idea? – Test 87 Apr 26 '18 at 02:58
  • Have you tried running it? It's just a warning in my case. – tedd Apr 26 '18 at 03:07
  • Hi Ted, please refer to my screenshot on top. Apps will crash after applied – Test 87 Apr 26 '18 at 04:25
  • What's the crash message? – tedd Apr 26 '18 at 04:58
  • layout attributes for supplementary item at index path ( {length = 2, path = 0 - 0}) changed from index path: ( {length = 2, path = 0 - 0}); element kind: (UICollectionElementKindSectionHeader); frame = (0 12; 414 40); zIndex = 10; to index path: ( {length = 2, path = 0 - 0}); element kind:(UICollectionElementKindSectionHeader); frame = (0 12; 414 40); zIndex = 7; without invalidating the layout' – Test 87 Apr 26 '18 at 05:04
  • Please try this solution that I've found https://stackoverflow.com/a/37563336/5142475 – tedd Apr 26 '18 at 05:24
  • Thx Ted. I have solved my problem by remove "return cell". Thanks anyway – Test 87 Apr 27 '18 at 07:11
  • It's my pleasure! Please vote for my answer if it did solved your problem. Thanks! – tedd Apr 27 '18 at 07:34
1

One option is to use a UIViewController instead of a UICollectionViewController. Add the view to use as your header to the view controller and then add a collection view below that header view.

This way the header is not part of the collection view and it won't scroll at all.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Hi rmaddy, currently I use @interface Product_HeadView : UICollectionReusableView in my header cell. You mean change this? – Test 87 Apr 26 '18 at 03:01