I have a UICollectionView
which shows photos. I have created the collectionview using UICollectionViewFlowLayout
. It works good but I would like to have spacing on margins. Is it possible to do that using UICollectionViewFlowLayout
or must I implement my own UICollectionViewLayout
?
-
the overwhelming issue is `contentInsetAdjustmentBehavior`. Take care! – Fattie Jul 13 '23 at 15:15
15 Answers
You can use the collectionView:layout:insetForSectionAtIndex:
method for your UICollectionView
or set the sectionInset
property of the UICollectionViewFlowLayout
object attached to your UICollectionView
:
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(top, left, bottom, right);
}
or
UICollectionViewFlowLayout *aFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[aFlowLayout setSectionInset:UIEdgeInsetsMake(top, left, bottom, right)];
Updated for Swift 5
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 25, left: 15, bottom: 0, right: 5)
}

- 2,898
- 2
- 22
- 29

- 3,746
- 1
- 15
- 10
-
49I don't seem to be getting left and right insets to work when using a vertical flow layout... – John Apr 04 '13 at 00:25
-
2Now overriding the sectionInset method of subclassed UICollectionViewFlowLayout also has no effect. Setting property described below works. – Dren Apr 29 '15 at 15:37
-
9NB: remember to add `UICollectionViewDelegateFlowLayout` to your list of ViewController delegates to use the method `insetForSectionAtIndex` – David Douglas Aug 12 '16 at 22:54
-
-
Setting up insets in Interface Builder like shown in the screenshot below
Will result in something like this:

- 1,255
- 1
- 9
- 6
-
2Great answer, just wanted to point out that you will also have to play with minimum spacing so that section inset works well. – Smit Yash Apr 11 '17 at 05:58
To add spacing on the entire UICollectionView
:
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*) collection.collectionViewLayout;
flow.sectionInset = UIEdgeInsetsMake(topMargin, left, bottom, right);
To play with the spacing between elements of the same row (column if you're scrolling horizontally), and their sizes:
flow.itemSize = ...;
flow.minimumInteritemSpacing = ...;
-
5This works, but the `collection.collectionViewLayout` needs a cast as in the example by @Pooja: `UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*) self.collectionViewLayout;` – jwj Dec 05 '13 at 18:56
-
Casting in swift `if let flow = collectionViewLayout as? UICollectionViewFlowLayout { flow.itemSize = CGSize(width: 100, height: 100) } ` – emily May 31 '16 at 13:51
Swift 4
let flow = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
// If you create collectionView programmatically then just create this flow by UICollectionViewFlowLayout() and init a collectionView by this flow.
let itemSpacing: CGFloat = 3
let itemsInOneLine: CGFloat = 3
flow.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
//collectionView.frame.width is the same as UIScreen.main.bounds.size.width here.
let width = UIScreen.main.bounds.size.width - itemSpacing * CGFloat(itemsInOneLine - 1)
flow.itemSize = CGSize(width: floor(width/itemsInOneLine), height: width/itemsInOneLine)
flow.minimumInteritemSpacing = 3
flow.minimumLineSpacing = itemSpacing
EDIT
If you want to change to scrollDirction
horizontally:
flow.scrollDirection = .horizontal
NOTE
If you set items in one lines isn't correctly, check if your collection view has paddings. That is:
let width = UIScreen.main.bounds.size.width - itemSpacing * CGFloat(itemsInOneLine - 1)
should be the collectionView width.

- 15,423
- 11
- 100
- 121
-
-
1@MartínDaniel Just set the ```backgroundColor``` of the ```collectionView```. Or whatever the super view. – William Hu Aug 02 '17 at 02:01
-
1
-
@user924 Margins at edges can be set with UIEdgeInsets(top: left: bottom: right: ). If scrolling vertically, set the left/right insets. If scrolling horizontally, set the top and bottom insets. – Marcy May 22 '19 at 22:31
Just to correct some wrong information in this page:
1- minimumInteritemSpacing: The minimum spacing to use between items in the same row.
The default value: 10.0.
(For a vertically scrolling grid, this value represents the minimum spacing between items in the same row.)
2- minimumLineSpacing : The minimum spacing to use between lines of items in the grid.

- 751
- 5
- 10
-
2This doesn't seem to affect spacing between sections, only between items within the same section? – Crashalot Jan 18 '16 at 17:32
-
@Crashalot - are you sure you don't mean minimumLineSpacing? i.e. every line of cells? There's also options for Section Insets if you really are using sections. – Chucky Jun 23 '16 at 16:45
-
This worked for me doing it via the storyboard interface. I was looking for a solution for horizontal only collection views. Thanks +10 – kemicofa ghost Nov 08 '16 at 15:23
Modern Swift, Automatic Layout Calculation
While this thread already contains a bunch of useful answers, I want to add a modern Swift version, based on William Hu's answer. It also improves two things:
- The spacing between different lines will now always match the spacing between items in the same line.
- By setting a minimum width, the code automatically calculates the number of items in a row and applies that style to the flow layout.
Here's the code:
// Create flow layout
let flow = UICollectionViewFlowLayout()
// Define layout constants
let itemSpacing: CGFloat = 1
let minimumCellWidth: CGFloat = 120
let collectionViewWidth = collectionView!.bounds.size.width
// Calculate other required constants
let itemsInOneLine = CGFloat(Int((collectionViewWidth - CGFloat(Int(collectionViewWidth / minimumCellWidth) - 1) * itemSpacing) / minimumCellWidth))
let width = collectionViewWidth - itemSpacing * (itemsInOneLine - 1)
let cellWidth = floor(width / itemsInOneLine)
let realItemSpacing = itemSpacing + (width / itemsInOneLine - cellWidth) * itemsInOneLine / max(1, itemsInOneLine - 1)
// Apply values
flow.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
flow.itemSize = CGSize(width: cellWidth, height: cellWidth)
flow.minimumInteritemSpacing = realItemSpacing
flow.minimumLineSpacing = realItemSpacing
// Apply flow layout
collectionView?.setCollectionViewLayout(flow, animated: false)

- 16,255
- 2
- 41
- 60

- 8,414
- 5
- 41
- 61
-
If `itemsInOneLine` is 1 then this will result in a NaN due to dividing by zero here: `itemsInOneLine / (itemsInOneLine - 1)` – TylerJames Feb 05 '20 at 20:34
-
1
use setMinimumLineSpacing:
and setMinimumInteritemSpacing:
on the UICollectionViewFlowLayout
-Object.

- 4,396
- 16
- 19
-
No it doesnt work, as expected. setMinimumLineSpacing is : The minimum spacing to use between items in the same row. And setMinimumInteritemSpacing is : The minimum spacing to use between lines of items in the grid. My question is about margins not space between elements. eg. Left and top spacing of first element. – Mert Dec 20 '12 at 11:26
-
assuming a vertical srollDirection you can use contentInset for top and bottom spacing of the first and last row. Also you could add your margins in your Cells. – Jonathan Cichon Dec 20 '12 at 11:53
Using collectionViewFlowLayout.sectionInset
or collectionView:layout:insetForSectionAtIndex:
are correct.
However, if your collectionView has multiple sections and you want to add margin to the whole collectionView, I recommend to use the scrollView contentInset :
UIEdgeInsets collectionViewInsets = UIEdgeInsetsMake(50.0, 0.0, 30.0, 0.0);
self.collectionView.contentInset = collectionViewInsets;
self.collectionView.scrollIndicatorInsets = UIEdgeInsetsMake(collectionViewInsets.top, 0, collectionViewInsets.bottom, 0);

- 1,998
- 21
- 23
To put space between CollectionItem
s use this
write this two Line in viewdidload
UICollectionViewFlowLayout *collectionViewLayout = (UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout;
collectionViewLayout.sectionInset = UIEdgeInsetsMake(<CGFloat top>, <CGFloat left>, <CGFloat bottom>, <CGFloat right>)

- 10,535
- 11
- 75
- 125

- 604
- 7
- 9
Set the insetForSectionAt
property of the UICollectionViewFlowLayout
object attached to your UICollectionView
Make sure to add this protocol
UICollectionViewDelegateFlowLayout
Swift
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets (top: top, left: left, bottom: bottom, right: right)
}
Objective - C
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(top, left, bottom, right);
}

- 8,460
- 5
- 41
- 56
In Objective-C
CGFloat spacing = 5;
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*)_habbitCollectionV.collectionViewLayout;
flow.sectionInset = UIEdgeInsetsMake(0, spacing, 0, spacing);
CGFloat itemsPerRow = 2;
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat oneMore = itemsPerRow + 1;
CGFloat width = screenRect.size.width - spacing * oneMore;
CGFloat height = width / itemsPerRow;
flow.itemSize = CGSizeMake(floor(height), height);
flow.minimumInteritemSpacing = spacing;
flow.minimumLineSpacing = spacing;
All you have to do is change the itemsPerRow value and it will update the number of items per row accordingly. Furthermore, you can change the spacing value if you want more or less general spacing.

- 9,289
- 12
- 69
- 108

- 12,189
- 5
- 77
- 85
For adding margins to specified cells, you can use this custom flow layout. https://github.com/voyages-sncf-technologies/VSCollectionViewCellInsetFlowLayout/
extension ViewController : VSCollectionViewDelegateCellInsetFlowLayout
{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForItemAt indexPath: IndexPath) -> UIEdgeInsets {
if indexPath.item == 0 {
return UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
}
return UIEdgeInsets.zero
}
}

- 81
- 4
In swift 4 and autoLayout, you can use sectionInset like this:
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.itemSize = CGSize(width: (view.frame.width-40)/2, height: (view.frame.width40)/2) // item size
layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10) // here you can add space to 4 side of item
collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout) // set layout to item
collectionView?.register(ProductCategoryCell.self, forCellWithReuseIdentifier: cellIdentifier) // registerCell
collectionView?.backgroundColor = .white // background color of UICollectionView
view.addSubview(collectionView!) // add UICollectionView to view

- 2,841
- 1
- 30
- 39
To add 10px separation between each section just write this
flowLayout.sectionInset = UIEdgeInsetsMake(0.0, 0.0,10,0);

- 2,070
- 2
- 18
- 18
-
when using UICollectionReusableView of kind UICollectionElementKindSectionFooter, your solution won't work – Pratik Jamariya Nov 14 '16 at 13:42