20

I have a simple UICollectionView which I have set with 0 spacing in InterfaceBuilder but when I populate the collection view with cells there is still some spacing. Is there something special and not immediately obvious that I need to do in order to actually see a collectionview cell with 0 spacing beyond setting it to have 0 spacing? Thanks.

EDIT* some code:

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];

    cell.backgroundColor = [UIColor clearColor];

    UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(2, 2, cell.frame.size.width -4, cell.frame.size.height -4)];
    lbl.backgroundColor = [UIColor clearColor];
    lbl.font = [UIFont boldSystemFontOfSize:20];
    lbl.text = [NSString stringWithFormat:@"$%0.0f", [[amountsArray objectAtIndex:indexPath.row] floatValue]];
    lbl.textAlignment = NSTextAlignmentCenter;
    lbl.layer.borderWidth = 1;

    [cell addSubview:lbl];
    [lbl release];

    return cell;
}

enter image description here

David
  • 3,285
  • 1
  • 37
  • 54
Zigglzworth
  • 6,645
  • 9
  • 68
  • 107

6 Answers6

26

Simple solution for your Query. Add this in your viewController's .m file:

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    ProductDetailViewController *HomeVC = [self.storyboard instantiateViewControllerWithIdentifier:@"ProductDetailView"];
    HomeVC.title = @"DemoProject";
    [self.navigationController pushViewController:HomeVC animated:YES];
}

- (UIEdgeInsets)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(0, 0, 0, 0); // top, left, bottom, right
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {

    return 0.0;
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
    return 0.0;
}
Mihir Oza
  • 2,768
  • 3
  • 35
  • 61
13

You have to create custom UICollectionViewLayout.

Space between the cells will be equal to cellSpacing.

final class CustomFlowLayout: UICollectionViewFlowLayout {

    let cellSpacing: CGFloat = 0

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        if let attributes = super.layoutAttributesForElements(in: rect) {
            for (index, attribute) in attributes.enumerated() {
                if index == 0 { continue }
                let prevLayoutAttributes = attributes[index - 1]
                let origin = prevLayoutAttributes.frame.maxX
                if (origin + cellSpacing + attribute.frame.size.width < self.collectionViewContentSize.width) {
                    attribute.frame.origin.x = origin + cellSpacing
                }
            }
            return attributes
        }
        return nil
    }

}
Beau Nouvelle
  • 6,962
  • 3
  • 39
  • 54
Vojtech Vrbka
  • 5,342
  • 6
  • 44
  • 63
  • This is definitely the solution to go with if you are using dynamically sized cells. – Fergal Rooney Jan 09 '17 at 17:19
  • Works great for me, thanks! Just FYI, I changed the x & width to y & height in order to get a masonry layout with horizontal scroll. – lundhjem Aug 17 '17 at 23:33
  • Be aware that although this will fit cells horizontally, there will be gap errors between the rows. Thank you anyway, though. – Womble Jun 13 '18 at 00:58
13

Swift 3 version of @MihirOza 's solution

Worked for both Horizontal and Vertical collection views

Code

// removing spacing
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return 0.0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0.0
}
Community
  • 1
  • 1
MBH
  • 16,271
  • 19
  • 99
  • 149
6

I solved this issue and got the layout I desired with the following:

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {

UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];



    cell.backgroundColor = [UIColor clearColor];

    //clear any contents on the cell
    for (UIView *subView in [cell subviews]) {
    [subView removeFromSuperview];
    }


    //Label to put on the cell
    UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(2, 2, cell.frame.size.width -4, cell.frame.size.height -4)];
    lbl.backgroundColor = [UIColor clearColor];
    lbl.textColor = [UIColor colorWithRed:[CPExtras RGBtoPercent:70] green:[CPExtras RGBtoPercent:92] blue:[CPExtras RGBtoPercent:105] alpha:1];
    lbl.font = [UIFont boldSystemFontOfSize:20];
    lbl.text = @"100";
    lbl.textAlignment = NSTextAlignmentCenter;

    //Give the cell a border
    cell.layer.borderColor = [[UIColor colorWithRed:[CPExtras RGBtoPercent:70] green:[CPExtras RGBtoPercent:92] blue:[CPExtras RGBtoPercent:105] alpha:0.5] CGColor];
    cell.layer.borderWidth = 0.5;


    [cell addSubview:lbl];

    [lbl release];





return cell;
}

In IB I had these measurement settings for the collectionview:

Collection View size

Collection view flow layout size

Zigglzworth
  • 6,645
  • 9
  • 68
  • 107
  • Where do you see this view? I can't find anything like that in IB. – Kirby Todd May 09 '14 at 09:54
  • `Collection View Size` is in the Size Inspector (ruler icon) for `Collection View`. `Collection View Flow Layout Size` is in the Size Inspector for `Collection View Flow Layout`. – Luqmaan May 22 '14 at 02:10
  • 5
    I think that removing all subviews from the cell and reinitializing them breaks the purpose of the cell reusability pattern. – rantunes Oct 01 '15 at 22:41
  • Yes the remove subview thing is not how this should be coded. I just whipped something together for my testing here so I didn't use a custom uicollectionviewcell which is what you should be using. – Zigglzworth Dec 24 '15 at 09:07
3

In order to actually have zero space, the number of cells and their width should be divisible by the collection view's own width, for example if you have 5 cells at a time with a width of 100px, then your collection view should have 500px in width, if it's larger then it will force a space between cells.

David Blue
  • 31
  • 1
2

The documentation for [UICollectionViewFlowLayout minimumInteritemSpacing] mentions:

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.

You may need to implement a custom layout to do this. The documentation can be found here, and an example here.

Pascal Bourque
  • 5,101
  • 2
  • 28
  • 45