UICollectionView spacing margins

IosUicollectionviewUikit

Ios Problem Overview


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?

Ios Solutions


Solution 1 - Ios

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

Solution 2 - Ios

Setting up insets in Interface Builder like shown in the screenshot below

Setting section insets for UICollectionView

Will result in something like this:

A collection view cell with section insets

Solution 3 - Ios

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 = ...;

Solution 4 - Ios

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.

enter image description here

Solution 5 - Ios

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.

Ref: http://developer.apple.com/library/ios/#documentation/uikit/reference/UICollectionViewFlowLayout_class/Reference/Reference.html

Solution 6 - Ios

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)

Solution 7 - Ios

use setMinimumLineSpacing: and setMinimumInteritemSpacing: on the UICollectionViewFlowLayout-Object.

Solution 8 - Ios

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

Solution 9 - Ios

To put space between CollectionItems 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>)

Solution 10 - Ios

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

Solution 11 - Ios

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.

enter image description here enter image description here

Solution 12 - Ios

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
    }
}

Solution 13 - Ios

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

Solution 14 - Ios

To add 10px separation between each section just write this

flowLayout.sectionInset = UIEdgeInsetsMake(0.0, 0.0,10,0);

Solution 15 - Ios

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMertView Question on Stackoverflow
Solution 1 - Iosmichael23View Answer on Stackoverflow
Solution 2 - IoskrzymarView Answer on Stackoverflow
Solution 3 - IosmarmorView Answer on Stackoverflow
Solution 4 - IosWilliam HuView Answer on Stackoverflow
Solution 5 - IosFelixView Answer on Stackoverflow
Solution 6 - IosfredpiView Answer on Stackoverflow
Solution 7 - IosJonathan CichonView Answer on Stackoverflow
Solution 8 - IosvmeyerView Answer on Stackoverflow
Solution 9 - IosPooja JalanView Answer on Stackoverflow
Solution 10 - IosPinkeshGjrView Answer on Stackoverflow
Solution 11 - IosScottyBladesView Answer on Stackoverflow
Solution 12 - IosMyrddinView Answer on Stackoverflow
Solution 13 - IosMohsen mokhtariView Answer on Stackoverflow
Solution 14 - IosGal BlankView Answer on Stackoverflow
Solution 15 - IosvishalView Answer on Stackoverflow