iosswiftuicollectionviewuicollectionreusableviewuicollectionviewflowlayout

CollectionViewSection Inset Does Not Consider Header/Footer Views


I have a collectionView with headers and footers. I want to add spacing at the end of the section.

I am using:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 0, left: 0, bottom: 16, right: 0)
}

However, this does not consider the footer view. therefore, the inset is added to the last index of that section. Is there any method or way to include the section footer before it applies the inset?

I need the inset under the footer view.

Illustration of existing functionality. (Yellow is the indexPath.item) the expected functionality is to have the inset (red) under the footer.

example image of section inset


Solution

  • As you rightly pointed out, UICollectionView's section is located between header and footer.

    If you want to add spacing below the footer, the best way would be to create custom footer view.

    optional func collectionView(_ collectionView: UICollectionView, 
    viewForSupplementaryElementOfKind kind: String, 
                              at indexPath: IndexPath) -> UICollectionReusableView
    

    Here are the docs for this method.

    Ideally, you would want to create a subclass for your custom Footer:]

    class CustomFooterView: UICollectionReusableView {
    
    }
    

    Then, register it in viewDidLoad:

    collectionView.register(CustomFooterView.self, forSupplementaryViewOfKind: .elementKindSectionFooter, withReuseIdentifier: "Your footer reuse ID")
    

    Then, you could return it as so:

    override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        if kind == UICollectionView.elementKindSectionFooter {
            return collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "Your footer reuse ID", for: indexPath)
        }
        else {
        }
    }
    

    Now you just need to ensure that auto layout is able to determine the size of your footer. So, add a label to your custom footer and ensure that its bottom constraint is equal to your desired padding.

    Note: there is one caveat. Now that you implement the method which returns your custom footer, and the same method is called for header, you would probably need to use a custom header as well. Or, you would need to register the standard UICollectionReusableView and deque it for your header.