0

I'm trying to subclass the UICollectionViewFlowLayout so that I can eliminate the space in between cells, because the flow layout only allows you to set a minimumInterItemSpacing, and not a maximumInterItemSpacing. I need a collectionView that scrolls vertically with dynamic cell heights and has no space in between the cells. Here is what I have tried in my subclass of UICollectionViewFlowLayout:

- (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray *answer = [[super layoutAttributesForElementsInRect:rect] mutableCopy];

    for(int i = 1; i < [answer count]; i++) {
        UICollectionViewLayoutAttributes *currentLayoutAttributes = answer[i];
        UICollectionViewLayoutAttributes *prevLayoutAttributes = answer[i - 1];
        NSInteger maximumSpacing = 0;
        NSInteger origin = prevLayoutAttributes.frame.origin.y + prevLayoutAttributes.frame.size.height;
        if(origin + maximumSpacing + currentLayoutAttributes.frame.size.height < self.collectionViewContentSize.height) {
            CGRect frame = currentLayoutAttributes.frame;
            frame.origin.y = origin + maximumSpacing;
            currentLayoutAttributes.frame = frame;
        }
    }
    return answer;
}

While this does seem to eliminate interitem spacing, it also produces odd side effects. Some cells end up way too tall, and others jumping around in size. Also, if I scroll really fast, some cells never show up at all. Does anybody know how I could best implement this seemingly simple thing?

Thanks

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Kyle Rosenbluth
  • 1,672
  • 4
  • 22
  • 38
  • Do you have multiple cells per row, or are they just stacked on top of each other like a table? – jrturton May 10 '14 at 21:42
  • Your problem here is that you are still returning the same number of layout attribute objects for a particular rect, even though you are moving the positions of the items in that rect so you can fit extra cells in there - that's why you're seeing gaps – jrturton May 10 '14 at 21:44

1 Answers1

0

You need to set a minimumLineSpacing on the layout:

For a vertically scrolling grid, this value represents the minimum spacing between successive rows. For a horizontally scrolling grid, this value represents the minimum spacing between successive columns. This spacing is not applied to the space between the header and the first line or between the last line and the footer.

You're setting the minimumInterItemSpacing, which is for items in the same row:

For a vertically scrolling grid, this value represents the minimum spacing between items in the same row. For a horizontally scrolling grid, this value represents the minimum spacing between items in the same column. This spacing is used to compute how many items can fit in a single line, but after the number of items is determined, the actual spacing may possibly be adjusted upward.

Your current issue is because you are moving items inside the rect that is passed to the layout, such that you can fit more items in there, but you are not adding extra items to fill that space, so you are seeing gaps. However, you don't need to override this at all, just set the line spacing property.

jrturton
  • 118,105
  • 32
  • 252
  • 268