UICollectionView Headers 重叠

UICollectionView Headers Overlapping

我有一个具有以下相关方法的 collectionView:

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

    if (kind == UICollectionElementKindSectionHeader) {
    Scoreboard *thisScoreboard = [self.scoreboards objectAtIndex:indexPath.section];

    ScoreboardReusableView *view = nil;

    view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
                                              withReuseIdentifier:@"scoreboardHeader"
                                                     forIndexPath:indexPath];

    //view.backgroundColor = [UIColor yellowColor];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 20)];
    //label.text = [NSString stringWithFormat:@"%@ vs %@", thisScoreboard.awayteam, thisScoreboard.hometeam];
    label.text = [NSString stringWithFormat:@"%ld", (long)indexPath.section];


    [view addSubview:label];

    return view;
    }
    return nil;
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
    return CGSizeMake(self.view.frame.size.width, 34);
}

但是,标签文本重叠。这是 collectionView 的两个屏幕截图。第 0 节和第 1 节(注意文本如何不重叠):

以及第 2 和第 3 节(此处和所有后续部分 header 的文本重叠):

我的 header xib ScoreboardReusableView 是完全空白的,因为无论我在其中放入什么(例如,UILabel 或 UIImageView,它都不会显示在 UICollectionView 中 Header ).我最好在 xib 中设计 header,但由于那不起作用,我尝试以编程方式进行,但现在标签重叠了。

ScoreboardReusableView 是空白的,但它是可重用的。您必须将 UILabel 放入 header xib 并在之后为其设置文本。

例如:

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

    if (kind == UICollectionElementKindSectionHeader) {
        Scoreboard *thisScoreboard = [self.scoreboards objectAtIndex:indexPath.section];

        ScoreboardReusableView *view = nil;

        view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
                                          withReuseIdentifier:@"scoreboardHeader"
                                                 forIndexPath:indexPath];

        view.label.text = [NSString stringWithFormat:@"%ld", (long)indexPath.section];

        return view;
    }
    return nil;
}

Collection 视图 re-use 个单元格和 header 个单元格。当 header 滚动到屏幕外时,它会被添加到 queue,并且将 re-used 用于下一个要在屏幕上滚动的 header。这意味着您在 collectionView:viewForSupplementaryElementOfKind: 方法中的配置代码将在不同索引路径的相同 header 视图中再次 运行。由于每次配置代码 运行 时您只是添加一个标签,因此它们将一个堆叠在另一个之上。

正确的方法是在 headerView 上添加一个标签 属性,这样它的文本就可以更改了。但是...

no matter what I put in it (e.g., a UILabel or a UIImageView), it would not show up

这是你真正的问题。你在 xib 上启用了自动布局吗?如果是这样,请务必为标签添加约束,否则它将具有零宽度和高度,从而产生您描述的效果。

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {

    UICollectionReusableView *reusableview=nil;
    reusableview = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];

    NSArray *viewsToRemove = [reusableview subviews];
    for (UIView *v in viewsToRemove) {
        [v removeFromSuperview];
    }

    if (reusableview==nil) {
        reusableview=[[UICollectionReusableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 30)];
    }
    reusableview.backgroundColor=[UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:1.0];

    UILabel *lblTitle=[[UILabel alloc] initWithFrame:CGRectMake(10, 0, [UIScreen mainScreen].bounds.size.width-90, 30)];
    [lblTitle setFont:[UIFont fontWithName:@"Ubuntu-Light" size:12]];

    lblTitle.textColor=HTAtHomeColor;
    [reusableview addSubview:lblTitle];

    UILabel *lblCount=[[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width-80, 0, 70, 30)];
    lblCount.textAlignment=NSTextAlignmentRight;
    lblCount.textColor=[UIColor blackColor];
    [lblCount setFont:[UIFont fontWithName:@"Ubuntu-Light" size:12]];
     lblCount.text=[NSString stringWithFormat:@"%d Section Header",indexPath.row];


    [reusableview addSubview:lblCount];

    return reusableview;
}
return nil;
}

Swift3个版本,希望对你有帮助

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    var reusableview: UICollectionReusableView?
    reusableview = nil
    reusableview = playersCollectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "collViewHeader", for: indexPath as IndexPath)
    if kind == UICollectionElementKindSectionHeader {

        //remove all previous subviews:
        if let views = reusableview?.subviews {
            for view in views {
                view.removeFromSuperview()
            }
        }
        //----------

        if reusableview == nil {
            reusableview = UICollectionReusableView.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 50))
        }

        //init label
        let label = UILabel.init(frame: CGRect(x: 10.0, y: 20.0, width: self.view.frame.width-20, height: 25.0)) //-20 from width to make it no go out of screen bounds
        label.textColor = UIColor.blue //you may set your color here :)
        label.adjustsFontSizeToFitWidth = true
        label.text = "your text here"

        reusableview?.addSubview(label)
    }
    return reusableview!
}