ios 删除空白空间,如果部分标题隐藏在 UICollectionView 中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20042900/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 22:24:56  来源:igfitidea点击:

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

iosiphoneios7uicollectionviewuicollectionreusableview

提问by Dinesh Raja

I have two sections in UICollectionView. I want to show a section header in UICollectionViewfor only 1st section. Not in 0th section.

我在UICollectionView. 我只想在第一节中显示节标题UICollectionView。不在第 0 节。

So I tried to return nilin viewForSupplementaryElementOfKind: method for section == 0and returns view for the section == 1.

于是,我就回nilviewForSupplementaryElementOfKind:方法section == 0并返回查看的section == 1

It crashes and shows below error:

它崩溃并显示以下错误:

Assertion failure in -[UICollectionView _createPreparedSupplementaryViewForElementOfKind:atIndexPath:withLayoutAttributes:applyAttributes]:

Here it is my code for the supplementary view.

这是我的补充视图代码。

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    UICollectionReusableView *sectionHeader = nil;
    if (kind == UICollectionElementKindSectionHeader && indexPath.section == 1) {
        sectionHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"EventSectionHeader" forIndexPath:indexPath];
        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;
    }

    return sectionHeader;
}

I have found that returning nil in viewForSupplementaryElementOfKind:method crashing for others too. Other answers suggesting to remove that method.

我发现在viewForSupplementaryElementOfKind:其他方法中返回 nil也会崩溃。其他答案建议删除该方法。

But I want to show section header for specific sections only. How to achieve that returning view for only one section? Thanks. Any help would be appreciated.

但我只想显示特定部分的部分标题。如何仅实现一个部分的返回视图?谢谢。任何帮助,将不胜感激。

EDIT:

编辑:

As @san said, I have updated code to hide the section header. It works. It hides the header. But I am still seeing the empty space in the place of section header. Expected results is there should be no space for section header, if it is hidden.

正如@san 所说,我已经更新了代码以隐藏部分标题。有用。它隐藏了标题。但我仍然看到节标题位置的空白区域。预期结果是节标题应该没有空间,如果它是隐藏的。

updated code:

更新代码:

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

    UICollectionReusableView *sectionHeader = nil;
    if (kind == UICollectionElementKindSectionHeader) {
        sectionHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"EventSectionHeader" forIndexPath:indexPath];
        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;
        if (indexPath.section == 0) {
            sectionHeader.hidden = YES;

        }else {
            sectionHeader.hidden = NO;
        }
    }

    return sectionHeader;
}

I even tried setting the frame for sectionHeader as @san said. But no luck. same result.

我什至尝试像@san 所说的那样为 sectionHeader 设置框架。但没有运气。同样的结果。

回答by Dinesh Raja

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.

正如@san 所说,我在下面的方法中设置了标题高度和宽度,直到现在。

- (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.

但是设置补充视图的帧大小并不是正确的方法。后来我在flowLayout里面找到了另一个方法,可以帮助我设置页眉和页脚的大小。

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 linkfor returning CGSizeZero in above method.

更新:由于有人质疑我在评论中的技能,因此附上 Apple文档链接以在上述方法中返回 CGSizeZero。

回答by CaptainRedmuff

The documentation for collectionView:viewForSupplementaryElementOfKind:atIndexPath:states:

collectionView:viewForSupplementaryElementOfKind:atIndexPath:状态的文档:

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.

此方法必须始终返回有效的视图对象。如果在特定情况下不需要补充视图,则布局对象不应为该视图创建属性。或者,您可以通过将相应属性的 hidden 属性设置为 YES 或将属性的 alpha 属性设置为 0 来隐藏视图。 要在流布局中隐藏页眉和页脚视图,您还可以设置这些视图的宽度和高度到 0。

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

考虑到您已经尝试将高度设置为零并将视图设置为隐藏,您应该子类化UICollectionViewFlowLayout并实现layoutAttributesForSupplementaryViewOfKind:atIndexPath:

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

检查 indexPath (正如您已经做的那样),nil如果您不想要该特定补充视图的任何布局属性,请返回。

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

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

回答by San

Documentation clearly says -

文件清楚地表明——

Return Value

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

返回值

已配置的补充视图对象。您不能从此方法返回 nil。

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.

此方法必须始终返回有效的视图对象。如果在特定情况下不需要补充视图,则布局对象不应为该视图创建属性。或者,您可以通过将相应属性的 hidden 属性设置为 YES 或将属性的 alpha 属性设置为 0 来隐藏视图。 要在流布局中隐藏页眉和页脚视图,您还可以设置这些视图的宽度和高度到 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;
}

回答by Nikunj Acharya

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

回答by Kaan Esin

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

您可以通过添加UICollectionViewDelegateFlowLayout委托并使用以下代码来隐藏/显示可重用的标题部分

- (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

所以你可以隐藏/显示它