I\'m working on a custom UICollectionViewLayout
that displays cells organized by day/week/month.
It is not scrolling smooth, and it looks like the lag i
Here is Altimac's answer converted to Swift 3:
cell.layer.shouldRasterize = true
cell.layer.rasterizationScale = UIScreen.main.scale
Also, it should be noted that this code goes in your collectionView delegate method for cellForItemAtIndexPath.
One more tip - to see an app's frames per second (FPS), open up Core Animation under Instruments (see screenshot).
Beside the listed answers (rasterize, auto-layout, etc.), you may also want to check for other reasons that potentially drags down the performance.
In my case, each of my UICollectionViewCell contains another UICollectionView (with about 25 cells each). When each of the cell is loading, I call the inner UICollectionView.reloadData(), which significantly drags down the performance.
Then I put the reloadData inside the main UI queue, the issue is gone:
DispatchQueue.main.async {
self.innerCollectionView.reloadData()
}
Carefully looking into reasons like these might help as well.
If you are implementing a grid layout you can work around this by using a single UICollectionViewCell
for each row
and add nested UIView
's to the cell
. I actually subclassed UICollectionViewCell
and UICollectionReusableView
and overrode the prepareForReuse
method to remove all of the subviews. In collectionView:cellForItemAtIndexPath:
I add in all of the subviews
that originally were cells setting their frame to the x
coordinate used in the original implementation, but adjusting it's y
coordinate to be inside the cell
. Using this method I was able to still use some of the niceties of the UICollectionView
such as targetContentOffsetForProposedContentOffset:withScrollingVelocity:
to align nicely on the top and left sides of a cell. I went from getting 4-6 FPS to a smooth 60 FPS.
Also don't forget to try to rasterize the layer of the cell:
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
I had 10 fps without that, and boom 55fps with! I'm not really familiar with GPU and compositing model, so what does it do exactly is not entirely clear to me, but basically it flatten the rendering of all subviews in only one bitmap (instead of one bitmap per subview?). Anyway I don't know if it has some cons, but it is dramatically faster!