UICollectionView does not obey zIndex UICollectionViewLayoutAttributes

The effect I'm trying to achieve is a kind of sticky header cell. It’s important for me that a sticky cell floats over others. Something like that:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Cell 0 β”‚ β”‚ β”œβ” β””β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ Cell 4 β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Cell 5 β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Cell 6 β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ 

Cells 4, 5, and 6 will display normally, and I'm building the attributes for cell 0 in my subclass of UICollectionViewFlowLayout during layoutAttributesForElementsInRect: All I do is call the super implementation, determine which cell I need to add, and then build the UICollectionViewLayoutAttributes(forCellWithIndexPath:) . Then I set zIndex to 1 (default is 0 ).

The problem I get is that the UICollectionView seems to always ignore zIndex

 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Cell 0 β”‚ β”‚β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β” └─ β”‚ β”‚ Cell 4 β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Cell 5 β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Cell 6 β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ 

Now I believe that it is possible to visually sort this using the 3D transform, but this does not work for me, since I do not want taps to come across in the cell located on top. Thus, in this example, I do not want Cell 4 to receive taps designed for Cell 0.

Does anyone have any ideas? This is on iOS 8.4.

+8
source share
5 answers

I did a separate project to cut all my extraneous code. In this process, I believe that I have found my solution.

override func initialLayoutAttributesForAppearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?
and
override func finalLayoutAttributesForDisappearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?

also did not use the new zIndex , so I think this caused it.

I just thought that I should send a response in case it appears in the search for someone else.

+3
source

Installing zIndex in a UICollectionViewLayout didn't work for me

I set zIndex inside the UICollectionViewController method

 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ customCell.layer.zPosition = 0; } 

My best guess is something between the layout and the controller, setting zIndex to something weird

+5
source

Updating UICollectionViewLayoutAttributes.zIndex does not work due to a UIKit error.

This code does the trick:

 // In your UICollectionViewCell subclass: override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) { super.apply(layoutAttributes) layer.zPosition = CGFloat(layoutAttributes.zIndex) // or any zIndex you want to set } 
+2
source

You need to set both values. ZIndex and 3DTransform parameter .

 class HeaderUnderCellsLayout: UICollectionViewFlowLayout { override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { guard let attributesArray = super.layoutAttributesForElements(in: rect) else { return nil } attributesArray.forEach { attributes in if attributes.representedElementCategory == .supplementaryView && attributes.representedElementKind == UICollectionView.elementKindSectionHeader { attributes.transform3D = CATransform3DMakeTranslation(0, 0, -10) attributes.zIndex = -200 } } return attributesArray } override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { let attributes = super.layoutAttributesForSupplementaryView(ofKind: elementKind, at: indexPath) attributes?.transform3D = CATransform3DMakeTranslation(0, 0, -10) attributes?.zIndex = -200 return attributes } } 
0
source

I encountered a similar problem in a subclass of UICollectionViewLayout , where the cell record did not account for updates to UICollectionViewLayoutAttributes.zIndex , but I was able to work around this problem by reloading the moved cells.

Specifically, I used this:

  collectionView.performBatchUpdates({ collectionView.moveItem(at:indexPath, to:newIndexPath) }) collectionView.reloadItems(at: [indexPath, newIndexPath]) 
0
source

All Articles