On Android I have item views with potentially large widths on a horizontal scrolling list. The view loads and draws chunks "images" as parts of the view become visible on the list. This is an optimization to avoid drawing all images at once as it would be wasteful and slow. The content drawn is essentially an audio waveform. Do to the ways things need to work I can't split the chunks as individual view items on a list. This strategy works perfect because of how android drawing architecture works.
Now I'm trying to use a similar pattern in iOS but I'm having some trouble and I'm not too sure how to come up with a solution.
In iOS I'm are using a UICollectionView
which draws large width Cells and we need that same optimization of loading and drawing only the visible chunks.
Solution 1:
Check what parts of the UIView
is visible and draw only those visible chunks. The problem with this solution is that as the UICollectionView
scrolls the UIView
doesn't draw the next chucks that are becoming visible. Here are examples of what I'm talking about.
UIView
loads initial chunks
These can be seen by their different chunk colors:
Scroll a bit
Black is shown and no content is loaded because there is no hint that the view needs to draw again so we can't load the next visible chunk.
Solution 2:
Use custom UIView
backed by a CATiledLayer
. This works perfect because it draws the tiles as they become visible while scrolling the UICollectionView
.
The problem is that drawing happens on the background thread or on the next drawing cycle if shouldDrawOnMainThread
is defined. This brings issues when the UIView
is resized or my internal zoom logic kicks. Things shift because the drawing cycle is not synchronized to the view resizing.
So how could I get notified like CATiledLayer
that a part is becoming visible and I could draw normally like a CALayer
backed UIView
?
UPDATE 1
I'm looking into using preferredLayoutAttributesFittingAttributes
as a way to check if a new chunk need to be drawn. This is called every time the cell is moved into a new position because of scrolling. Hopefully, this isn't a bad idea. :)
- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes
UPDATE 2
After much testing and playing around. Using solution 1 is not an option. When a UIView
reaches a huge width memory usage goes off the roof while using CATiledLayer
memory usage is at minimal as I guess one would expect. :/