9

For some reason in new collectionview compositional layout zIndex property for section header is not working. I have tried below code to achieve the behaviour.

func configureCategorySectionLayout() -> NSCollectionLayoutSection {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))
        let layoutItem = NSCollectionLayoutItem(layoutSize: itemSize)

        let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(80), heightDimension: .absolute(105))
        let groupItem = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [layoutItem])

        let sectionLayout = NSCollectionLayoutSection(group: groupItem)

        let sectionItem = createAddressSectionHeader()
        sectionItem.zIndex = 2
        sectionItem.pinToVisibleBounds = true
        sectionLayout.boundarySupplementaryItems = [sectionItem]
        sectionLayout.contentInsets = .init(top: 0, leading: 10, bottom: 0, trailing: 10)
        sectionLayout.orthogonalScrollingBehavior = .continuous
        return sectionLayout
    }

func createAddressSectionHeader() -> NSCollectionLayoutBoundarySupplementaryItem {
        let sectionHeaderSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(65))
        let sectionHeaderItem = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: sectionHeaderSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
        return sectionHeaderItem
    }

enter image description here

enter image description here

CrackIt
  • 606
  • 1
  • 5
  • 15

2 Answers2

4

You can fix this behaviour by adding the following snippet to your UICollectionReusableView subclass (and/or UICollectionViewCell subclass):

public override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
     super.apply(layoutAttributes)
     self.layer.zPosition = CGFloat(layoutAttributes.zIndex)
}
PhM
  • 104
  • 3
  • i will try it. Thanks! – CrackIt Apr 03 '20 at 04:49
  • 1
    Well i must say its better then before. It comes to front now but header just disappear in the middle of scrolling when i scroll forward. It become visible when i scroll backwards. I mean before the second section sticks to first in between it disappear. – CrackIt Apr 04 '20 at 11:51
  • @CrackIt I noticed the same behaviour and it's so damn annoying. I fixed the zLayer issue but headers are disappearing anyway, even with `pinToVisibleBounds` set to `true` – Adam Nov 25 '20 at 17:44
  • @Adam exactly, its not pinning for some reason. – CrackIt Nov 27 '20 at 03:15
  • Whoa, this was helpful to find—thank you @PhM This fixed the zIndex issue for me in CompositionalLayout with a custom reusable supplemental view – thefaj Mar 17 '21 at 21:12
4

I had the same issue using iOS 13 + Compositional Layout. The cells in my collectionview were going on top of the sticky headers. I solved it by setting the header's zIndex in the compositional layout config, and then overriding ApplyLayoutAttributes in my reusableView class AND my collectionviewCell class.

class FoodCategorySectionHeader: UICollectionReusableView {

...

override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
      super.apply(layoutAttributes)
      layer.zPosition = CGFloat(layoutAttributes.zIndex)
   }
}
class FoodCell: UICollectionViewCell {

...

override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
       super.apply(layoutAttributes)
      layer.zPosition = 0.0
   }
}

The relevant section from my compositional layout code:

func createFoodSection(using section: FoodCategory) -> NSCollectionLayoutSection {

...      

      let layoutSectionHeader = createSectionHeader()
      layoutSectionHeader.zIndex = 1000
      layoutSectionHeader.pinToVisibleBounds = true
      
...

      layoutSection.boundarySupplementaryItems = [layoutSectionHeader]
      
      return layoutSection
   }
theogood
  • 85
  • 1
  • 1
  • 7
  • 1
    seems like overriding attributes from collectionview cell as well as from reusable view will do the trick. need to test this but I am no longer working on the project bdw thanks for the help really appreciate. – CrackIt Nov 12 '20 at 12:58
  • no problem @CrackIt! feel free to mark the answer 'accepted' if you feel it's right :) – theogood Nov 12 '20 at 15:39
  • well, luckily I still have the project but I tried your solution and unfortunately its not working for me – CrackIt Nov 14 '20 at 10:28
  • 1
    Observing the collection view it seems it automatically sets `zIndex` to UInt64.max on pinned header attributes but sometimes it brings it back to the value in `NSCollectionLayoutBoundarySupplementaryItem` (1 by default), hence the flickering. Setting `zIndex` to a bigger value on the `NSCollectionLayoutBoundarySupplementaryItem` worked for me. – tompitt Apr 27 '22 at 10:28
  • This works, but you can still end up in a state where the boundarySupplementaryItem displays above the cell and user interaction is not enabled. – PatPatchPatrick Nov 04 '22 at 22:04