Graphics Reference
In-Depth Information
result in pop-in of new images as we scroll. This problem isn't specific to CATiledLayer ; it
also affects our GCD-based version.
Even with all the image loading and caching techniques we've discussed, you will
sometimes find that an image is simply too large to load and display in real time. As
mentioned in Chapter 13, a full-screen Retina-quality image on an iPad has a resolution of
2048×1536 and consumes 12MB of RAM (uncompressed). The third-generation iPad's
hardware simply is not capable of loading, decompressing, and displaying such an image
within one-sixtieth of a second. Even if we load on a background thread to avoid animation
stutter, we will still see gaps in our carousel.
We could display a placeholder image in the gap while the real image loads, but that's
really just plastering over the problem. We can do better than that.
Resolution Swapping
Retina resolution (according to Apple's marketing) represents the smallest pixel size that
the human eye is capable of distinguishing at a normal viewing distance. But that only
applies to static pixels. When you observe a moving image, your eye is much less sensitive
to detail, and a lower-resolution image is indistinguishable from Retina quality.
If we need to load and display very large moving images quickly, the simple solution is to
cheat , and display smaller (or rather, lower resolution ) images while the carousel is
moving, and then swap in the full-res images when it comes to a stop. This means that we
need to store two copies of each of our images at different resolutions, but fortunately that's
common practice anyway as we still need to support both Retina and non-Retina devices.
If you are loading the image from a remote source, or the user's photo library, and don't
already have a lower resolution version readily available, you can generate it dynamically
by drawing the larger image into a smaller CGContext and then saving the resultant smaller
image somewhere for later use.
To schedule the image swap, we can take advantage of a couple of delegate methods called
by UIScrollView (as well as other scrollview-based controls such as UITableView and
UICollectionView ) as part of its UIScrollViewDelegate protocol:
- ( void )scrollViewDidEndDragging:( UIScrollView *)scrollView
willDecelerate:( BOOL )decelerate;
- ( void )scrollViewDidEndDecelerating:( UIScrollView *)scrollView;
You can use these methods to detect when the carousel has come to rest, and defer loading
the high-resolution versions of your images until that point. You'll find that the changeover
is pretty much imperceptible as long as the low-res and high-res versions of the image
match up perfectly in terms of color balance. (Be sure to generate them both on the same
machine, using the same graphics application or script, so that they do.)
Search WWH ::




Custom Search