Skip to content

Instantly share code, notes, and snippets.

@eddiekaiger
Last active August 13, 2023 11:28
Show Gist options
  • Save eddiekaiger/bdae29273c3153ae1114233e7320b586 to your computer and use it in GitHub Desktop.
Save eddiekaiger/bdae29273c3153ae1114233e7320b586 to your computer and use it in GitHub Desktop.
A cell class and collectionView layout that allows for dynamically sized cells
import Foundation
import UIKit
class AutoSizingCollectionViewCell: UICollectionViewCell {
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
layoutIfNeeded()
layoutAttributes.bounds.size.height = systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
return layoutAttributes
}
}
class DynamicFlowLayout: UICollectionViewFlowLayout {
override init() {
super.init()
estimatedItemSize = UICollectionViewFlowLayout.automaticSize
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
guard let layoutAttributes = super.layoutAttributesForItem(at: indexPath) else { return nil }
guard let collectionView = collectionView else { return nil }
let collectionWidth = collectionView.safeAreaLayoutGuide.layoutFrame.width
layoutAttributes.bounds.size.width = collectionWidth - sectionInset.left - sectionInset.right
return layoutAttributes
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard let superLayoutAttributes = super.layoutAttributesForElements(in: rect) else { return nil }
guard scrollDirection == .vertical else { return superLayoutAttributes }
let computedAttributes = superLayoutAttributes.compactMap { layoutAttribute in
layoutAttribute.representedElementCategory == .cell ?
layoutAttributesForItem(at: layoutAttribute.indexPath) : layoutAttribute
}
return computedAttributes
}
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
guard let collectionView = collectionView else { return false }
return !newBounds.size.equalTo(collectionView.bounds.size)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment