AlignedCollectionViewFlowLayout
AlignedCollectionViewFlowLayout copied to clipboard
Collection view header getting overlapped
Collection view header getting overlapped while setting
let alignedFlowLayout = collectionView?.collectionViewLayout as? AlignedCollectionViewFlowLayout
alignedFlowLayout?.horizontalAlignment = .left
alignedFlowLayout?.verticalAlignment = .top
The issue is that verticalAlignmentAxisForLine is considering the supplementary views with the cells. Apply these changes below, and everything should work as expected.
private func verticalAlignmentAxisForLine(
with layoutAttributes: [UICollectionViewLayoutAttributes]
) -> AlignmentAxis<VerticalAlignment>? {
let cellAttributes = layoutAttributes.filter {
return $0.representedElementCategory == .cell
}
guard let firstAttribute = cellAttributes.first
else {
return nil
}
let indexPath = firstAttribute.indexPath
switch verticalAlignment {
case .top:
let minY = cellAttributes.reduce(CGFloat.greatestFiniteMagnitude) {
min($0, $1.frame.minY)
}
return AlignmentAxis(
alignment: .top,
position: minY
)
case .bottom:
let maxY = cellAttributes.reduce(0) {
max($0, $1.frame.maxY)
}
return AlignmentAxis(
alignment: .bottom,
position: maxY
)
default:
let centerY = firstAttribute.center.y
return AlignmentAxis(
alignment: .center,
position: centerY
)
}
}
fileprivate func isFrame(
for firstItemAttributes: UICollectionViewLayoutAttributes,
inSameLineAsFrameFor secondItemAttributes: UICollectionViewLayoutAttributes
) -> Bool {
guard let lineWidth = contentWidth
else
{
return false
}
let firstItemFrame = firstItemAttributes.frame
let lineFrame = CGRect(
x: sectionInset.left,
y: firstItemFrame.origin.y,
width: lineWidth,
height: firstItemFrame.size.height
)
return lineFrame.intersects(
secondItemAttributes.frame
)
}
open override func layoutAttributesForSupplementaryView(
ofKind elementKind: String,
at indexPath: IndexPath
) -> UICollectionViewLayoutAttributes? {
let attributes = super.layoutAttributesForSupplementaryView(
ofKind: elementKind,
at: indexPath
)
return attributes
}
private func setFrame(
forLayoutAttributes layoutAttributes: UICollectionViewLayoutAttributes
) {
if layoutAttributes.representedElementCategory == .cell { // Do not modify header views etc.
let indexPath = layoutAttributes.indexPath
if let newFrame = layoutAttributesForItem(
at: indexPath
)?.frame {
layoutAttributes.frame = newFrame
}
}
if layoutAttributes.representedElementKind == UICollectionView.elementKindSectionHeader {
let indexPath = layoutAttributes.indexPath
if let newFrame = layoutAttributesForSupplementaryView(
ofKind: UICollectionView.elementKindSectionHeader,
at: indexPath
)?.frame {
layoutAttributes.frame = newFrame
}
}
}