Removing empty space, if the section header is hidden in the UICollectionView

杀马特。学长 韩版系。学妹 提交于 2019-11-28 17:47:13

At last, I found an answer for my question. I have missed something. Anyway sorry for other fellow users.

I set the header height and width inside the below method till now as @san said.

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

But It is not the correct method to set the frame size of supplementary views. Later I found another method inside the flowLayout, which helps me to set the header and footer sizes.

This really works well for me:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return CGSizeZero;
    }else {
        return CGSizeMake(CGRectGetWidth(collectionView.bounds), 135);
    }
}

UPDATE: Since someone questioned about my skill in comments, attaching Apple Documentation link for returning CGSizeZero in above method.

The documentation for collectionView:viewForSupplementaryElementOfKind:atIndexPath: states:

This method must always return a valid view object. If you do not want a supplementary view in a particular case, your layout object should not create the attributes for that view. Alternatively, you can hide views by setting the hidden property of the corresponding attributes to YES or set the alpha property of the attributes to 0. To hide header and footer views in a flow layout, you can also set the width and height of those views to 0.

Considering you have already tried setting the height to zero and setting the view to be hidden, you should subclass UICollectionViewFlowLayout and implement layoutAttributesForSupplementaryViewOfKind:atIndexPath:

Check the indexPath (as you already do) and return nil if you don't want any layout attributes for that specific supplementary view.

- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    if([indexPath section] == 0)
    {
         return nil;
    }

    return [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
}

Documentation clearly says -

Return Value

A configured supplementary view object. You must not return nil from this method.

So you need follow -

This method must always return a valid view object. If you do not want a supplementary view in a particular case, your layout object should not create the attributes for that view. Alternatively, you can hide views by setting the hidden property of the corresponding attributes to YES or set the alpha property of the attributes to 0. To hide header and footer views in a flow layout, you can also set the width and height of those views to 0.

Coming to your code, below snippet should work for you:

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    UICollectionReusableView *sectionHeader = nil;
    if (kind == UICollectionElementKindSectionHeader) {
        sectionHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"EventSectionHeader" forIndexPath:indexPath];

        if(indexPath.section == 1)
          {
             sectionHeader.layer.borderWidth = .5f;
             sectionHeader.layer.borderColor = [UIColor colorWithRed:221.0 / 255.0 green:223.0 / 255.0 blue:220.0 / 255.0 alpha:1.0].CGColor;
          }
        else
        {
          sectionHeader.frame = CGRectZero;
          sectionHeader.hidden = YES;
        }
    }

    return sectionHeader;
}

In my case I have given inset to sections so it was giving me empty space So if you have implemented following method, do it in below way

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        if <condition for which you want to hide section>{
            return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        }else{
            return UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        }
    }
Kaan Esin

You can hide/show your reusable header section by adding UICollectionViewDelegateFlowLayout delegate and using below code

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
if (self.isForSearch) { //---> for hiding
    return CGSizeMake(0,0);
}
else{//---> for showing
    return ((UICollectionViewFlowLayout*)self.collectionChoosePlanView.collectionViewLayout).headerReferenceSize;
}
}

So you can hide/show it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!