How to apply different contentInset only for contents cells but not for a header in UICollectionView

10,362

Solution 1

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.

Solution 2

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.

Share:
10,362
Bigair
Author by

Bigair

Updated on June 26, 2022

Comments

  • Bigair
    Bigair about 2 years

    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
    Bigair almost 8 years
    Would it be possible to set the header width not shorter than UICollectionView but as wide as the screen?
  • Robert J. Clegg
    Robert J. Clegg almost 8 years
    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.
  • Bigair
    Bigair almost 8 years
    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.
  • Robert J. Clegg
    Robert J. Clegg almost 8 years
    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 ?
  • Bigair
    Bigair almost 8 years
    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.
  • Berry Blue
    Berry Blue over 4 years
    This should be the selected answer.
  • Dhaval H. Nena
    Dhaval H. Nena over 4 years
    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) }