11

I use insetForSectionAtIndex method to set contentInset for a section in my collection view and I don't want to apply that inset to a header of the section. I need the header width to be as wide as the screen.

ConentInset

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
    if section == 1 {
        return UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15)
    }

    return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}

Header

override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {

    let header = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: opsMainDescriptionSegmentedControlCellId, forIndexPath: indexPath) as! MyHeader

    return header
}
Bigair
  • 1,452
  • 3
  • 15
  • 42

2 Answers2

19

I just had to do this exact same thing in one of my project.

The solution I applied:

In Storyboard, my collection view takes up the full screen with Auto-Layout constraints.

In viewDidLoad:

collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

I set the collectionView delegate to self and also conform to the

UICollectionViewDelegateFlowLayout protocol.

You then have access to the method you've used where I return another UIEdgeInsets

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

        return UIEdgeInsets(top: 15, left: 20, bottom: 15, right: 20)

    }

and it worked for me.

See how it looked in the end.

enter image description here

Hope this will be able to help others.

Edouard Barbier
  • 1,815
  • 2
  • 19
  • 32
  • 1
    This should be the selected answer. – Berry Blue Oct 13 '19 at 22:40
  • TIP : Don't use **collectionView.contentInset** property, instead use delegate method that is as below ```swift func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { return UIEdgeInsets(top: 15, left: 20, bottom: 15, right: 20) } ``` – Dhaval H. Nena Jan 09 '20 at 07:53
1

You cannot do this. UICollectionViews headers need to be as wide as the UICollectionView itself. If you want the header to be shorter (width) than the UICollectionView - my suggestion is to use a separate UIView inside the header and set the header to clear. That way it will appear that its shorter than the width of the UICollectionView.

Robert J. Clegg
  • 7,231
  • 9
  • 47
  • 99
  • Would it be possible to set the header width not shorter than UICollectionView but as wide as the screen? – Bigair Jul 20 '16 at 08:14
  • Seems I misread your question. What you're currently doing, should work. Make sure UICollectionView's width is set to the same as the parent view's width. – Robert J. Clegg Jul 20 '16 at 08:17
  • If I the width of a header is wider than collectionView, XCode logs error message. The app won't crash but the header width would be resized to the width of the collection view. – Bigair Jul 20 '16 at 08:35
  • That's the expected behaviour. Set the collectionView's frame to the same as screen size. Then just set content inset on the collectionView itself not the header. The header will be the side of the collectionView - and the collection view will have an inset on 15 each side... that should give you your desired affect. Whats the error Xcode gives ? – Robert J. Clegg Jul 20 '16 at 08:37
  • There was a typo on the title of the question... I need to set contentInset only for regular cell but not for header. So this case, Header is wider than other part of the section. – Bigair Jul 20 '16 at 08:45