Upon creating a custom collection view layout reloadData does not work
Upon creating a custom collection view layout reloadData does not work after I did an infinite scroll which calls a new data from the api
I suspect that it is because of the fixed items called from the collectionview. How will I able to update it?
protocol CustomCollectionViewLayoutDelegate: class {
func collectionView(
collectionView: UICollectionView,
heightForItemAtIndexPath indexPath: IndexPath
) -> CGFloat
}
public class CustomCollectionViewLayout: UICollectionViewLayout {
weak var delegate: CustomCollectionViewLayoutDelegate!
public var numberOfColumns: Int = 1
private var cache: [UICollectionViewLayoutAttributes] = [UICollectionViewLayoutAttributes]()
private var contentHeight: CGFloat = 0
private var contentWidth: CGFloat {
guard let collectionView = collectionView else {
return 0
}
let insets = collectionView.contentInset
return collectionView.bounds.width - (insets.left + insets.right)
}
public override var collectionViewContentSize: CGSize {
return CGSize(
width: self.contentWidth,
height: self.contentHeight
)
}
public override func prepare() {
if cache.isEmpty {
let columnWidth: CGFloat = self.contentWidth / CGFloat(self.numberOfColumns)
var xOffset: [CGFloat] = [CGFloat]()
for column in 0...numberOfColumns{
xOffset.append(CGFloat(column) * columnWidth)
}
var yOffset: [CGFloat] = [CGFloat](repeating: 0, count: self.numberOfColumns)
var column: Int = 0
for item in 0 ..< collectionView!.numberOfItems(inSection: 0) {
// for item in 0 ..< collectionView!.numberOfItems(inSection: 0) {
let indexPath: IndexPath = IndexPath(item: item, section: 0)
let height = delegate.collectionView(
collectionView: collectionView!,
heightForItemAtIndexPath: indexPath
)
let frame: CGRect = CGRect(
x: xOffset[column],
y: yOffset[column],
width: columnWidth,
height: height
)
let attributes: UICollectionViewLayoutAttributes = UICollectionViewLayoutAttributes(
forCellWith: indexPath
)
attributes.frame = frame
self.cache.append(attributes)
self.contentHeight = max(contentHeight, frame.maxY)
yOffset[column] = yOffset[column] + height
column = column < (self.numberOfColumns - 1) ? (column + 1) : 0
}
}
}
public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var visibleLayoutAttributes = [UICollectionViewLayoutAttributes]()
// Loop through the cache and look for items in the rect
for attributes in cache {
if attributes.frame.intersects(rect) {
visibleLayoutAttributes.append(attributes)
}
}
return visibleLayoutAttributes
}
public override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return cache[indexPath.item]
}
}
I just need to be able to use reloadData to update my infinite scroll data
I suggest to add this function to your CustomCollectionViewLayout
func reloadData(){
self.cache = [UICollectionViewLayoutAttributes]()
}
and then when you want to reload your data
if let layout = self.collectionView.collectionViewLayout as? CustomCollectionViewLayout {
layout.reloadData()
}
collectionView.reloadData()
deleting if cache.isEmpty may result in reuse of your layout
just remove if cache.isEmpty you should be fine
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With