Search code examples
iosobjective-cuicollectionviewuicollectionviewcelluicollectionviewlayout

UICollectionView Headers Overlapping


I have a collectionView with the following relevant methods:

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

However, the label text is overlapping. Here are two screenshots of the collectionView. Sections 0 and 1 (notice how the text does NOT overlap):

enter image description here

And sections 2 and 3 (the text overlaps here and on all subsequent section headers): enter image description here

My header xib ScoreboardReusableView is COMPLETELY blank because no matter what I put in it (e.g., a UILabel or a UIImageView, it would not show up in the UICollectionView Header). Preferably I would design the header in a xib, but since that's not working I tried to do it programmatically, but now labels are overlapping.


Solution

  • Collection views re-use cells and headers. When a header is scrolled offscreen it is added to a queue, and will be re-used for the next header to be scrolled onscreen. That means your configuration code in collectionView:viewForSupplementaryElementOfKind: method will be run again on the same header view at different indexPaths. Since you're just adding a label every time your configuration code runs, they will stack one on top of the other.

    The correct approach is to have a label property on the headerView, so that its text can be changed. But...

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

    This is your real issue. Do you have autolayout enabled on the xib? If so be sure to add constraints for the label, otherwise it will have zero width and height, giving the effect you describe.