UICollectionView: add spacing between header and items

18,137

Solution 1

You are basically talking about adding a top margin to the collection view section, for that you would set top inset for the section. To do it in code, implement insetForSectionAtIndex:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 10.0, left: 1.0, bottom: 1.0, right: 1.0)
}

If you don't want to implement the insetForSectionAtIndex, you could also do something like this in an appropriate method e.g. viewDidLoad:

let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.sectionInset = UIEdgeInsets(top: 10.0, left: 1.0, bottom: 1.0, right: 1.0)

In Interface Builder, Select collection view and change the value for Section Insets -> Top as shown in the image below:

enter image description here

NOTE: This only works if you are using Flow Layout.

Solution 2

One way you can do is to increase your header container's heigh using

collectionView(_:layout:referenceSizeForHeaderInSection:)

Example:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    return CGSize(width: 0, height: yourHeaderContentHeight + yourHeaderMarginToCell)
}

Edit:

func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
    let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "YourID", forIndexPath: indexPath)

    let yourCustomView = UIView(frame: CGRect(x: 0, y: 0, width: yourHeaderWidth, height: yourHeaderHeight))

    headerView.addSubview(yourCustomView)

    return headerView
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    return CGSize(width: yourHeaderWidth, height: yourHeaderHeight + yourHeaderMargin)
}
Share:
18,137

Related videos on Youtube

Liumx31
Author by

Liumx31

Updated on November 01, 2022

Comments

  • Liumx31
    Liumx31 over 1 year

    I want to add some spacing between my header and the actual items, which currently look like this:

    screenshot1

    func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
        // Create header
        switch kind{
            case UICollectionElementKindSectionHeader:
                let headerView = iconCollectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "customIconHeaderView", forIndexPath: indexPath) as! CustonIconHeaderView
                headerView.setUp() //add whatever into the view
                return headerView
            default:
                assert(false, "Unexpected element kind")
        }
    
    }
    
    • Eric Armstrong
      Eric Armstrong about 5 years
      you could add a spacer cell as the first cell in the section. not an ideal implementation I know, but fool proof
  • Liumx31
    Liumx31 over 8 years
    that just increased the height of the header, i'm using a custom view for the header though, i don't know if that affects anything
  • Breek
    Breek over 8 years
    For example, your custom header view is 40 pt height and the referenceSizeForHeaderInSection is 60 which will provide 20 pt gap on the bottom if you set your custom header view's frame properly :)
  • Liumx31
    Liumx31 over 8 years
    how do i set the custom view's height, I'm doing everything in code. Do i do it in viewForSupplementaryElementOfKind?
  • Liumx31
    Liumx31 over 8 years
    I'm doing everything in code, when i change insetForSectionAtIndex, it increases the top margin for the header as well. So everything moves down.
  • ishaq
    ishaq over 8 years
    are you saying you don't want to implement the insetForSectionAtIndex method? if so, yes you could do this too: let layout = collection.collectionViewLayout as! UICollectionViewFlowLayout; layout.sectionInset = UIEdgeInsets(top: 10.0, left: 1.0, bottom: 1.0, right: 1.0);
  • Liumx31
    Liumx31 over 8 years
    no, I implemented insetForSectionAtIndex, which is currently UIEdgeInsets(top: 0.0, left: 20.0, bottom: 30.0, right: 20.0), but when i change top to say 10, not only the items move down, the header also moves down. but what i want is just spacing between the section header and the items.
  • ishaq
    ishaq over 8 years
    strange, how have you returned your section header? you are returning it from your func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView right? I just tried it, it works for me.
  • Liumx31
    Liumx31 over 8 years
    oh so you're suggesting using headerView as a container view? The way I'm doing it is I customized a UIView to be the headerView, so I just need to dequeue it and return it in viewForSupplementaryElementOfKind.
  • Breek
    Breek over 8 years
    Correct :) but if you don't want to have your customView inside the headerView, you can always draw your view and make a white(any color) bar on the bottom to simulate same visual effect
  • Liumx31
    Liumx31 over 8 years
    Never mind, it was because I was also using a custom flow layout. Thanks.
  • Max
    Max over 4 years
    This seems like the easiest way to add space between the header and the items. If you build your collection view and header in IB, this is easy to do by setting all of your constraints to the top of the header view and making sure they don't move as you change its size