By Vishal Singh


2013-06-21 06:55:09 8 Comments

How do I set cell spacing in a section of UICollectionView? I know there is a property minimumInteritemSpacing I have set it to 5.0 still the spacing is not appearing 5.0. I have implemented the flowout delegate method.

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

    return 5.0;
}

still I am not getting the desired result. I think its the minimum spacing . Isn't there any way by which I can set the maximum spacing?

simulator sc

23 comments

@vishalwaka 2018-08-23 10:06:51

I have tried iago849's answer and it worked.

Swift 4

open override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    guard let answer = super.layoutAttributesForElements(in: rect) else {
        return nil
    }
    let count = answer.count
    for i in 1..<count {
        let currentLayoutAttributes = answer[i]
        let prevLayoutAttributes = answer[i-1]
        let origin = prevLayoutAttributes.frame.maxX
        if (origin + CGFloat(spacing) + currentLayoutAttributes.frame.size.width) < self.collectionViewContentSize.width && currentLayoutAttributes.frame.origin.x > prevLayoutAttributes.frame.origin.x {
            var frame = currentLayoutAttributes.frame
            frame.origin.x = origin + CGFloat(spacing)
            currentLayoutAttributes.frame = frame
        }
    }
    return answer
}

Here is the link for the github project. https://github.com/vishalwaka/MultiTags

@AMayes 2018-02-14 15:58:51

Simple code for spacing

let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.minimumInteritemSpacing = 10 // Some float value

@Vincent Joy 2015-12-12 15:36:49

Remember, it is minimum line space, not minimum inter item spacing or cell space. Because your collectionView's scroll direction is HORIZONTAL.

If it was vertical then you need to set cell space or inter item space for horizontal space between cells and line spacing for vertical space between cells.

Objective-C version

- (CGFloat)collectionView:(UICollectionView *)collectionView
                       layout:(UICollectionViewLayout*)collectionViewLayout
    minimumLineSpacingForSectionAtIndex:(NSInteger)section
    {
        return 20;
    }

Swift version:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 20
}

@Bangalore 2015-12-15 06:41:54

now bottom space is gone when i return 0; how to remove right side space ?

@Vincent Joy 2015-12-15 07:13:02

Hey, I didn't understand your question very well. But I think insetForSectionAtIndex is what you are looking for. - (UIEdgeInsets)collectionView:(UICollectionView*)collectionVi‌​ew layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { return UIEdgeInsetsMake(5, 10, 5, 10); }

@Swati 2018-06-29 12:27:17

It is minimum line spacing for both horizontal and vertical.

@Umair_UAS 2019-02-22 11:02:48

You saved my day (Y).

@Boris 2017-12-11 10:22:32

If u want to tweak the spacing without touching the actual cell size, this is the solution that worked best for me. #xcode 9 #tvOS11 #iOS11 #swift

So in UICollectionViewDelegateFlowLayout, change implement the next methods, the trick is u have to use both of them, and the documentation was not really pointing me to think in that direction. :D

open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return cellSpacing
}

public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return cellSpacing
}

@Zhanserik 2017-09-21 05:00:47

My solution in Swift 3 cell line spacing like in Instagram:

enter image description here

lazy var collectionView: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.backgroundColor = UIColor.rgb(red: 227, green: 227, blue: 227)
    cv.showsVerticalScrollIndicator = false
    layout.scrollDirection = .vertical
    layout.minimumLineSpacing = 1
    layout.minimumInteritemSpacing = 1
    return cv
}()

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    switch UIDevice.current.modelName {
    case "iPhone 4":
        return CGSize(width: 106, height: 106)
    case "iPhone 5":
        return CGSize(width: 106, height: 106)
    case "iPhone 6,7":
        return CGSize(width: 124, height: 124)
    case "iPhone Plus":
        return CGSize(width: 137, height: 137)
    default:
        return CGSize(width: frame.width / 3, height: frame.width / 3)
    }
}

How to detect device programmaticlly: https://stackoverflow.com/a/26962452/6013170

@topLayoutGuide 2017-05-18 10:42:33

Swift 3 Version

Simply create a UICollectionViewFlowLayout subclass and paste this method.

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let answer = super.layoutAttributesForElements(in: rect) else { return nil }

        for i in 1..<answer.count {
            let currentAttributes = answer[i]
            let previousAttributes = answer[i - 1]

            let maximumSpacing: CGFloat = 8
            let origin = previousAttributes.frame.maxX

            if (origin + maximumSpacing + currentAttributes.frame.size.width < self.collectionViewContentSize.width && currentAttributes.frame.origin.x > previousAttributes.frame.origin.x) {
                var frame = currentAttributes.frame
                frame.origin.x = origin + maximumSpacing
                currentAttributes.frame = frame
            }
        }

        return answer
}

@NiravS 2017-07-29 08:13:32

After that how to apply in the code??

@Womble 2018-06-13 01:13:15

This works for horizontal fitting, but gaps will remain between rows, even if minimumLineSpacingForSectionAt is set to return 0, and layout.minimumLineSpacing is set to 0. Also, a touch in the collectionView will crash the app, due to the first loop being out of range.

@Vadim Bulavin 2016-10-26 11:36:11

Answer for Swift 3.0, Xcode 8

1.Make sure you set collection view delegate

class DashboardViewController: UIViewController {
    @IBOutlet weak var dashboardCollectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        dashboardCollectionView.delegate = self
    }
}

2.Implement UICollectionViewDelegateFlowLayout protocol, not UICollectionViewDelegate.

extension DashboardViewController: UICollectionViewDelegateFlowLayout {
    fileprivate var sectionInsets: UIEdgeInsets {
        return .zero
    }

    fileprivate var itemsPerRow: CGFloat {
        return 2
    }

    fileprivate var interitemSpace: CGFloat {
        return 5.0
    }

    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize {
        let sectionPadding = sectionInsets.left * (itemsPerRow + 1)
        let interitemPadding = max(0.0, itemsPerRow - 1) * interitemSpace
        let availableWidth = collectionView.bounds.width - sectionPadding - interitemPadding
        let widthPerItem = availableWidth / itemsPerRow

        return CGSize(width: widthPerItem, height: widthPerItem)
    }

    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        insetForSectionAt section: Int) -> UIEdgeInsets {
        return sectionInsets
    }

    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 0.0
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return interitemSpace
    }
}

@Edward Potter 2016-12-12 22:28:22

Think you can remove the public there. Should work fine, and consistent with all other func(s).

@Vadim Bulavin 2016-12-22 14:28:03

@EdwardPotter done. Thank you for noticing.

@Annjawn 2017-07-02 05:26:11

Would this work for vertical scroll collection view? I have collection view where it should show 2 cells horizontally on devices like iPhone 6s and 6s Plus, but should show just one cell for anything lower than that i.e. 5s,5 and SE. My current code is working but in 6s Plus device the gap between the cells is just too much and looks ugly and I am trying to lessen that gap and that's the only requirement since all other devices are working as per my design.

@jerik 2013-07-09 17:13:20

Supporting the initial question. I tried to get the spacing to 5px on the UICollectionView but this does not work, as well with a UIEdgeInsetsMake(0,0,0,0)...

On a UITableView I can do this by directly specifying the x,y coordinates in a row...

enter image description here

Heres my UICollectionView code:

#pragma mark collection view cell layout / size
- (CGSize)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return [self getCellSize:indexPath];  // will be w120xh100 or w190x100
    // if the width is higher, only one image will be shown in a line
}

#pragma mark collection view cell paddings
- (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 5.0;
}

Update: Solved my problem, with the following code.

enter image description here

ViewController.m

#import "ViewController.h"
#import "MagazineCell.h" // created just the default class. 

static NSString * const cellID = @"cellID";

@interface ViewController ()

@end

@implementation ViewController

#pragma mark - Collection view
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 30;
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    MagazineCell *mCell = (MagazineCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];

    mCell.backgroundColor = [UIColor lightGrayColor];

    return mCell;
}

#pragma mark Collection view layout things
// Layout: Set cell size
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    NSLog(@"SETTING SIZE FOR ITEM AT INDEX %d", indexPath.row);
    CGSize mElementSize = CGSizeMake(104, 104);
    return mElementSize;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
    return 2.0;
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
    return 2.0;
}

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

@end

@cynistersix 2014-12-17 02:52:48

This is a much better answer. Take a look at the callbacks you can adjust in the UICollectionViewDelegateFlowLayout and you can see how this can be tweaked.

@xi.lin 2015-08-27 08:55:03

I thins this can only work when the width of item + spacing is equals with the width of uicollectionview.

@Nhon Nguyen 2015-12-16 02:59:39

Seem to be not working anymore on swift 2.0

@Jayprakash Dubey 2016-08-12 06:37:41

@jerik : What is Swift version for this code?

@jerik 2016-08-12 06:54:31

@JayprakashDubey currently i am not fit in swift. You have to try it. Good luck

@Mobile Bloke 2017-04-01 12:04:28

Where are you specifying the width between the cells of 5px?

@jerik 2017-04-03 15:47:28

@MobileBloke It's a long time since I wrote this code. Currently I have no glue, I think I reduced the width between the cells to 4px or 2px.

@Cindeselia 2017-07-14 11:50:44

Much better answer than the accepted one, mainly because subclassing UICollectionViewLayout just to override one method seems like overkill, and is no trivial matter given all the other methods that need to be overridden.

@Yun CHEN 2017-02-16 08:19:41

I have problem with the accepted answer, so I updated it, this is working for me:

.h

@interface MaxSpacingCollectionViewFlowLayout : UICollectionViewFlowLayout
@property (nonatomic,assign) CGFloat maxCellSpacing;
@end

.m

@implementation MaxSpacingCollectionViewFlowLayout

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

    if (attributes.count <= 0) return attributes;

    CGFloat firstCellOriginX = ((UICollectionViewLayoutAttributes *)attributes[0]).frame.origin.x;

    for(int i = 1; i < attributes.count; i++) {
        UICollectionViewLayoutAttributes *currentLayoutAttributes = attributes[i];
        if (currentLayoutAttributes.frame.origin.x == firstCellOriginX) { // The first cell of a new row
            continue;
        }

        UICollectionViewLayoutAttributes *prevLayoutAttributes = attributes[i - 1];
        CGFloat prevOriginMaxX = CGRectGetMaxX(prevLayoutAttributes.frame);
        if ((currentLayoutAttributes.frame.origin.x - prevOriginMaxX) > self.maxCellSpacing) {
            CGRect frame = currentLayoutAttributes.frame;
            frame.origin.x = prevOriginMaxX + self.maxCellSpacing;
            currentLayoutAttributes.frame = frame;
        }
    }
    return attributes;
}

@end

@Mantas Laurinavičius 2017-01-27 20:57:40

Previous versions did not really work with sections > 1. So my solution was found here https://codentrick.com/create-a-tag-flow-layout-with-uicollectionview/. For the lazy ones:

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    let attributesForElementsInRect = super.layoutAttributesForElements(in: rect)
    var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]()
    // use a value to keep track of left margin
    var leftMargin: CGFloat = 0.0;
    for attributes in attributesForElementsInRect! {
        let refAttributes = attributes 
        // assign value if next row
        if (refAttributes.frame.origin.x == self.sectionInset.left) {
            leftMargin = self.sectionInset.left
        } else {
            // set x position of attributes to current margin
            var newLeftAlignedFrame = refAttributes.frame
            newLeftAlignedFrame.origin.x = leftMargin
            refAttributes.frame = newLeftAlignedFrame
        }
        // calculate new value for current margin
        leftMargin += refAttributes.frame.size.width + 10
        newAttributesForElementsInRect.append(refAttributes)
    }

    return newAttributesForElementsInRect
}

@Aamir 2016-10-13 11:55:48

I have found very easy way to configure spacing between cells or rows by using IB.

Just select UICollectionView from storyboard/Xib file and click in Size Inspector as specified in below image.

enter image description here

For configuring space programatically use following properties.

1) For setting space between rows.

[self.collectionView setMinimumLineSpacing:5];

2) For setting space between items/cells.

[self.collectionView setMinimumInteritemSpacing:5];

@Vishal Singh 2016-10-14 08:53:33

Thats minimum space, which will be greater than specified value and not always the specified value.

@torrao 2016-08-12 23:22:50

The above solution by vojtech-vrbka is correct but it triggers a warning:

warning:UICollectionViewFlowLayout has cached frame mismatch for index path - cached value: This is likely occurring because the flow layout subclass Layout is modify attributes returned by UICollectionViewFlowLayout without copying them

The following code should fix it:

class CustomViewFlowLayout : UICollectionViewFlowLayout {

   let cellSpacing:CGFloat = 4

   override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
       let original = super.layoutAttributesForElementsInRect(rect)

       if let original = original {
           let attributes = NSArray.init(array: original, copyItems: true) as! [UICollectionViewLayoutAttributes]

           for (index, attribute) in attributes.enumerate() {
                if index == 0 { continue }
                let prevLayoutAttributes = attributes[index - 1]
                let origin = CGRectGetMaxX(prevLayoutAttributes.frame)
                if(origin + cellSpacing + attribute.frame.size.width < self.collectionViewContentSize().width) {
                    attribute.frame.origin.x = origin + cellSpacing
                }
            }
            return attributes
       }
       return nil
   }
}

@Womble 2018-06-13 01:17:06

Like the other answers on SO that use this approach, this does work for fitting cells across the width of the collectionView, but intermittent, variable-height gaps still remain between rows. This may be be a limitation of the way CollectionView actually renders.

@iago849 2013-10-17 14:16:01

I know that the topic is old, but in case anyone still needs correct answer here what you need:

  1. Override standard flow layout.
  2. Add implementation like that:

    - (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
        NSArray *answer = [super layoutAttributesForElementsInRect:rect];
    
        for(int i = 1; i < [answer count]; ++i) {
            UICollectionViewLayoutAttributes *currentLayoutAttributes = answer[i];
            UICollectionViewLayoutAttributes *prevLayoutAttributes = answer[i - 1];
            NSInteger maximumSpacing = 4;
            NSInteger origin = CGRectGetMaxX(prevLayoutAttributes.frame);
    
            if(origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width) {
                CGRect frame = currentLayoutAttributes.frame;
                frame.origin.x = origin + maximumSpacing;
                currentLayoutAttributes.frame = frame;
            }
        }
        return answer;
    }
    

where maximumSpacing could be set to any value you prefer. This trick guarantees that the space between cells would be EXACTLY equal to maximumSpacing!!

@Jonny 2014-02-14 09:54:03

So, where do we put this?

@iago849 2014-04-02 08:48:02

Hey Jonny, inherit from standard Flow Layout and just copy and paste this method into your class.

@TamilKing 2014-06-20 13:25:15

I paste this code but this not calling?

@Brock Boland 2014-12-29 16:34:24

Note that you don't need to make a mutableCopy: you're not mutating the contents of the array, but mutating the objects within it.

@iago849 2015-02-18 11:21:04

Brock Boland, right, nice entry!

@pash3r 2016-03-05 10:19:36

maybe I do something wrong or this idea is not working for 100%, because when I scroll to the end I see that some cells are overlay each other :(

@iago849 2016-03-22 10:59:33

Flow layout as specified in answer

@Evgeniy Kleban 2016-07-12 13:14:42

Awesome!!! I wonder why Apple force us to have 10 points spacing..

@iago849 2016-07-12 13:47:16

Default spacing in layout, like many other things :)

@chrisoneiota 2016-09-09 09:32:03

Great post. I did encounter an error with it upsetting the formatting of the last line of the layout in some circumstances. To resolve I changed the if to AND an additional condition: if(origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width && currentLayoutAttributes.frame.origin.x > prevLayoutAttributes.frame.origin.x) {

@Ashok R 2016-11-06 15:37:54

Great post i am getting extra space as @chrisoneiota mentioned and i sloved using his code. :-)

@Jeremy Sh 2016-12-15 14:08:18

does anyone have a swift 3 solution to this? Im finding it hard to create an extension and override this properly

@Karaban 2017-02-24 12:35:51

Works just like a charm. But can you deeply explain how does it work ?

@iago849 2017-03-14 13:04:22

layoutAttributesForElementsInRect is just a overriden method of Flow Layout. I simply move X points of each default frame (you see call super) so that frames are 4 pixels between each other

@strawnut 2017-06-11 07:37:10

This answer is not MAXIMUM spacing. Just set to maximumSpacing variable value.<br> If want to set to the real maximum spacing, need to additional condition: if(originX + self.maximumInteritemSpacing + CGRectGetWidth(currentLayoutAttributes.frame) < self.collectionViewContentSize.width && CGRectGetMinX(currentLayoutAttributes.frame) - originX > self.maximumInteritemSpacing) {

@user3344977 2016-05-24 17:48:57

I have a horizontal UICollectionView and subclassed UICollectionViewFlowLayout. The collection view has large cells, and only shows one row of them at a time, and the collection view fits the width of the screen.

I tried iago849's answer and it worked, but then I found out I didn't even need his answer. For some reason, setting the minimumInterItemSpacing does nothing. The spacing between my items/cells can be entirely controlled by minimumLineSpacing.

Not sure why it works this way, but it works.

@samwize 2015-12-01 04:40:59

The voted answer (and also the swift version) has a small issue: there will be a big spacing on the right.

This is because the flow layout is customised to make the cell spacing exact, with a float left behaviour.

My solution is to manipulate the section inset, so that the section is align center, yet the spacing is exactly as specified.

In screenshot below, the item/line spacing is exactly 8pt, while the section left & right inset will be bigger than 8pt (to make it center aligned):

evenly spaced cells

Swift code as such:

private let minItemSpacing: CGFloat = 8
private let itemWidth: CGFloat      = 100
private let headerHeight: CGFloat   = 32

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    // Create our custom flow layout that evenly space out the items, and have them in the center
    let layout = UICollectionViewFlowLayout()
    layout.itemSize = CGSize(width: itemWidth, height: itemWidth)
    layout.minimumInteritemSpacing = minItemSpacing
    layout.minimumLineSpacing = minItemSpacing
    layout.headerReferenceSize = CGSize(width: 0, height: headerHeight)

    // Find n, where n is the number of item that can fit into the collection view
    var n: CGFloat = 1
    let containerWidth = collectionView.bounds.width
    while true {
        let nextN = n + 1
        let totalWidth = (nextN*itemWidth) + (nextN-1)*minItemSpacing
        if totalWidth > containerWidth {
            break
        } else {
            n = nextN
        }
    }

    // Calculate the section inset for left and right. 
    // Setting this section inset will manipulate the items such that they will all be aligned horizontally center.
    let inset = max(minItemSpacing, floor( (containerWidth - (n*itemWidth) - (n-1)*minItemSpacing) / 2 ) )
    layout.sectionInset = UIEdgeInsets(top: minItemSpacing, left: inset, bottom: minItemSpacing, right: inset)

    collectionView.collectionViewLayout = layout
}

@DaftWooly 2016-06-17 10:50:10

I get a 'NSInvalidArgumentException', reason: '*** setObjectForKey: object cannot be nil (key: <NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0})' uncaught exception.

@DaftWooly 2016-06-17 10:52:20

... if I'm not mistaken, your while loop is equivalent to : let n = Int((containerWidth + minItemSpacing)/((itemWidth+minItemSpacing)))

@Dima Gimburg 2017-04-05 21:35:08

Didn't used the code as is, but this gave me the best reference for implementing my out flow layout for the collection view. cheers

@Vojtech Vrbka 2015-08-26 11:11:38

Swift version of the most popular answer. Space between the cells will be equal to cellSpacing.

class CustomViewFlowLayout : UICollectionViewFlowLayout {

    let cellSpacing:CGFloat = 4

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

@Ashok R 2016-11-06 14:09:22

super.layoutAttributesForElements(in: rect) is returning nil any idea?

@Womble 2018-06-13 01:19:10

Like all the other methods that use this, this does not work properly for multiple rows. Intermittent, rounding-error-style gaps will remain between rows, even with the appropriate delegate methods and properties set to use 0. It may be a UICollectionView rendering issue.

@LASoft 2014-10-21 19:06:18

Try this code to ensure you have a spacing of 5px between each item:

- (UIEdgeInsets)collectionView:(UICollectionView *) collectionView 
                        layout:(UICollectionViewLayout *) collectionViewLayout 
        insetForSectionAtIndex:(NSInteger) section {

    return UIEdgeInsetsMake(0, 0, 0, 5); // top, left, bottom, right
}

- (CGFloat)collectionView:(UICollectionView *) collectionView
                   layout:(UICollectionViewLayout *) collectionViewLayout
  minimumInteritemSpacingForSectionAtIndex:(NSInteger) section {    
    return 5.0;
}

@Conduit 2014-10-21 19:15:17

Please format your code as a code block so it will display nicely on SO.

@luk2302 2015-05-01 18:14:38

I stumbled upon a similar problem as OP. Unfortunately the accepted answer did not work for me since the content of the collectionView would not be centered properly. Therefore I came up with a different solution which only requires that all items in the collectionView are of the same width, which seems to be the case in the question:

#define cellSize 90

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    float width = collectionView.frame.size.width;
    float spacing = [self collectionView:collectionView layout:collectionViewLayout minimumInteritemSpacingForSectionAtIndex:section];
    int numberOfCells = (width + spacing) / (cellSize + spacing);
    int inset = (width + spacing - numberOfCells * (cellSize + spacing) ) / 2;

    return UIEdgeInsetsMake(0, inset, 0, inset);
}

That code will ensure that the value returned by ...minimumInteritemSpacing... will be the exact spacing between every collectionViewCell and furthermore guarantee that the cells all together will be centered in the collectionView

@p0lAris 2015-06-06 15:37:48

That's pretty cool. But I was wondering if a similar solution could be applied to vertical spacing between elements

@luk2302 2015-06-06 15:46:32

Vertical spacing in case you have horizontal scrolling?

@Jason Moore 2014-05-08 12:40:04

Using a horizontal flow layout, I was also getting a 10 points spacing between cells. To remove the spacing I needed to set minimumLineSpacing as well as minimumInterItemSpacing to zero.

UICollectionViewFlowLayout *flow = [[UICollectionViewFlowLayout alloc] init];
flow.itemSize = CGSizeMake(cellWidth, cellHeight);
flow.scrollDirection = UICollectionViewScrollDirectionHorizontal;
flow.minimumInteritemSpacing = 0;
flow.minimumLineSpacing = 0;

Also, if all your cells are the same size, it's simpler and more efficient to set the property on the flow layout directly instead of using delegate methods.

@Matt H 2014-09-23 19:13:30

Surprisingly, minimumLineSpacing affects the horizontal space between cells.

@Wingzero 2015-02-03 07:35:49

ME too, I need a horizontal scroll and zero spacing between cells, and minimumLineSpacing = 0 is the key.

@Ziewvater 2015-10-16 21:26:13

I was able to get this effect without using minimumInteritemSpacing. Just setting minimumLineSpacing = 0 on my horizontal layout removed the horizontal spacing between items.

@lancejabr 2017-02-24 21:19:08

If you think about it, the horizontal distance between items IS the line spacing for a horizontally flowing layout. The line spacing is the vertical distance between items in a typical, vertically flowing layout.

@Salman Zaidi 2013-06-21 07:30:08

Define UICollectionViewDelegateFlowLayout protocol in your header file.

Implement following method of UICollectionViewDelegateFlowLayout protocol like this:

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
    return UIEdgeInsetsMake(5, 5, 5, 5);
}

Click Here to see Apple Documentation of UIEdgeInsetMake method.

@Anil Varghese 2013-06-21 07:03:37

Please note the property name minimumInterItemSpacing . This will be the minimum spacing between the items not the exact spacing. If you set minimumInterItemSpacing to some value you can assure that spacing wont be a value less than that. But there is a chance get a higher value.

Actually the spacing between items depends on several factors itemSize and sectionInset. Collection view dynamically place the contents based on these values. So you cannot assure the exact spacing. You should do some trial and error with sectionInset and minimumInterItemSpacing.

@Vishal Singh 2013-06-21 07:05:56

yes so is there any way i can set maximum cell spacing?

@NightFury 2014-01-23 07:38:01

@Anil edge insects? :D

@Nestor 2014-01-29 17:00:04

There may be bugs in your sectionInsects.

@Nestor 2014-01-31 09:30:15

insect == bug && insect != inset :)

@Matt 2013-11-17 11:54:33

I'm using monotouch, so the names and code will be a bit different, but you can do this by making sure that the width of the collectionview equals (x * cell width) + (x-1) * MinimumSpacing with x = amount of cells per row.

Just do following steps based on your MinimumInteritemSpacing and the Width of the Cell

1) We calculate amount of items per row based on cell size + current insets + minimum spacing

float currentTotalWidth = CollectionView.Frame.Width - Layout.SectionInset.Left - Layout.SectionInset.Right (Layout = flowlayout)
int amountOfCellsPerRow = (currentTotalWidth + MinimumSpacing) / (cell width + MinimumSpacing)

2) Now you have all info to calculate the expected width for the collection view

float totalWidth =(amountOfCellsPerRow * cell width) + (amountOfCellsPerRow-1) * MinimumSpacing

3) So the difference between the current width and the expected width is

float difference = currentTotalWidth - totalWidth;

4) Now adjust the insets (in this example we add it to the right, so the left position of the collectionview stays the same

Layout.SectionInset.Right = Layout.SectionInset.Right + difference;

@Nikola Kirev 2013-06-21 07:03:06

Try playing around with this method:

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView
                    layout:(UICollectionViewLayout*)collectionViewLayout
    insetForSectionAtIndex:(NSInteger)section {

    UIEdgeInsets insets = UIEdgeInsetsMake(?, ?, ?, ?);

    return insets;
}

@Diego A. Rincon 2016-03-11 19:14:21

This only works for spacing between sections, not cells

Related Questions

Sponsored Content

26 Answered Questions

5 Answered Questions

1 Answered Questions

2 Answered Questions

[SOLVED] UICollectionView cells not spacing at all

3 Answered Questions

1 Answered Questions

[SOLVED] UICollectionView Max Cell Spacing?

1 Answered Questions

1 Answered Questions

[SOLVED] UICollectionViewLayout. Where are all my items?

2 Answered Questions

[SOLVED] Adjust UICollectionView's Width

Sponsored Content