Uicollectionview Scrolling Choppy When Loading Cells

UICollectionview Scrolling choppy when loading cells

So anybody having scrolling issues should do this

add these 2 lines after your dequeue

cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

Visible lag while scrolling two way scrolling UICollectionView with large number of cells (250,000 or more)

By taking advantage of the layoutAttributesForElementsInRect(rect: CGRect) with your known cell size you don't need to cache your attributes and could just calculate them for a given rect as the collectionView requests them. You would still need to check for the boundary cases of 0 and the maximum section/row counts to avoid calculating unneeded or invalid attributes but that can be easily done in where clauses around the loops. Here's a working example that I've tested with 1000 sections x 1000 rows and it works just fine without lagging on the device:

Edit: I've added the biggerRect so that attributes can be pre-calculated for before the scrolling gets there. From your edit it looks like you're still caching the attributes which I don't think is needed for performance. Also it's going to lead to a much larger memory footprint with the more scrolling you do. Also is there a reason your don't want to use the supplied CGRect from the callback rather than manually calculate one from the contentOffset?

class LuckGameCollectionViewLayout: UICollectionViewFlowLayout {

let CELL_HEIGHT = 50.0
let CELL_WIDTH = 50.0

override func collectionViewContentSize() -> CGSize {
let contentWidth = Double(collectionView!.numberOfItemsInSection(0)) * CELL_WIDTH
let contentHeight = Double(collectionView!.numberOfSections()) * CELL_HEIGHT
return CGSize(width: contentWidth, height: contentHeight)
}

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let biggerRect = rect.insetBy(dx: -2048, dy: -2048)
let startIndexY = Int(Double(biggerRect.origin.y) / CELL_HEIGHT)
let startIndexX = Int(Double(biggerRect.origin.x) / CELL_WIDTH)
let numberOfVisibleCellsInRectY = Int(Double(biggerRect.height) / CELL_HEIGHT) + startIndexY
let numberOfVisibleCellsInRectX = Int(Double(biggerRect.width) / CELL_WIDTH) + startIndexX
var attributes: [UICollectionViewLayoutAttributes] = []

for section in startIndexY..<numberOfVisibleCellsInRectY
where section >= 0 && section < self.collectionView!.numberOfSections() {
for item in startIndexX..<numberOfVisibleCellsInRectX
where item >= 0 && item < self.collectionView!.numberOfItemsInSection(section) {
let cellIndex = NSIndexPath(forItem: item, inSection: section)
if let attrs = self.layoutAttributesForItemAtIndexPath(cellIndex) {
attributes.append(attrs)
}
}
}
return attributes
}

override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
let xPos = Double(indexPath.row) * CELL_WIDTH
let yPos = Double(indexPath.section) * CELL_HEIGHT
let cellAttributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
cellAttributes.frame = CGRect(x: xPos, y: yPos, width: CELL_WIDTH, height: CELL_HEIGHT)
return cellAttributes
}
}


Related Topics



Leave a reply



Submit