For some reason my scrollbar always appears underneath the collection view section header. Any help is greatly appreciated!
-
1This is an iOS 11 bug. The scroll bar is correctly positioned in iOS 10. – nathangitter Oct 11 '17 at 17:39
4 Answers
I found a workaround. This issue is that the zPosition
of the header view is being set by the collection view incorrectly. To fix this, we will always ensure that the zPosition
is our desired value.
Create a CALayer
subclass which prevents the zPosition
from being anything other than 0.
class CustomLayer: CALayer {
override var zPosition: CGFloat {
get { return 0 }
set {}
}
}
Then set the layer class of your collection view header to this new subclass.
class MyHeaderView: UICollectionReusableView {
// your other custom code here
override class var layerClass: AnyClass {
get { return CustomLayer.self }
}
}
This is an iOS 11 bug, as this issue does not occur in iOS 10. Hopefully this works well enough until the bug is fixed.

- 9,607
- 3
- 33
- 42
-
1Thanks for sharing, this seems like a better solution than what I was doing. I basically just set the headerCell as a regular cell. but yours seem cleaner. – Soja Oct 14 '17 at 00:04
-
1
-
4
Same concept, but here is a simpler workaround that doesn't require your UICollectionReusableView
instances to use a subclass.
Conform to UICollectionViewDelegate
(if you don't already) and implement willDisplaySupplementaryView protocol method like so:
func collectionView(_ collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, at indexPath: IndexPath) {
view.layer.zPosition = 0.0
}
Tested in iOS 11.2.1.

- 17,051
- 8
- 55
- 72
-
@Nathan The bug only exists for iOS 11, so this code has no effect for iOS <=10. That being said, I have not tested this on iOS 11.0 or 11.1. – Keller Feb 02 '18 at 18:12
Here is my alternative which seems to work better on iOS12 when subclassing UICollectionReusableView
.
final class BasicCollectionSectionHeader: UICollectionReusableView {
override var layer: CALayer {
let layer = super.layer
layer.zPosition = 0 // make the header appear below the collection view scroll bar
return layer
}
}

- 3,097
- 2
- 26
- 27
With a long-scrolling, async-loading collection, this alternative may offer slightly better performance.
class MyHeaderView: UICollectionReusableView {
override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
layer.zPosition = 0
}
}

- 1,866
- 15
- 14