42

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

所以我尝试nilviewForSupplementaryElementOfKind: 方法中section == 0返回并为section == 1.

它崩溃并显示以下错误:

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

这是我的补充视图代码。

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

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

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

编辑:

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

更新代码:

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

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

4

5 回答 5

84

最后,我找到了我的问题的答案。我错过了一些东西。无论如何,对不起其他用户。

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

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

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

这对我来说真的很有效:

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

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

于 2013-11-20T12:13:24.020 回答
23

状态的文档collectionView:viewForSupplementaryElementOfKind:atIndexPath:

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

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

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

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

    return [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
}
于 2013-11-20T11:54:01.577 回答
9

文件清楚地表明 -

返回值

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

所以你需要遵循 -

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

来到你的代码,下面的代码片段应该适合你:

- (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;
}
于 2013-11-18T08:29:19.513 回答
0

在我的情况下,我已经给部分插入,所以它给了我空白空间所以如果你已经实现了以下方法,请按以下方式进行

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)
        }
    }
于 2019-01-30T11:15:22.840 回答
-1

您可以通过添加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;
}
}

所以你可以隐藏/显示它

于 2016-04-12T15:20:53.927 回答