Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preload/predisplay tiles in a CATiledLayer?

On the iPhone (though I imagine it's an equally valid question in Cocoa) I have a UIScrollView around a UIView backed by a CATiledLayer. The way it works by default is to load any uncached/unfetched tiles when my viewport scrolls over a blank section of the CATiledLayer.

What I would like to know is if there's a way to trigger CATiledLayer to load a tile that's not actively being displayed? I would like to, for example, preload all tiles contiguous to the currently displayed tile while they are still offscreen, thus avoiding flashing a blank screen that fades in to the image once it's loaded asynchronously.

Any ideas?

like image 415
jemmons Avatar asked Jul 15 '09 20:07

jemmons


1 Answers

I don't think CATiledLayer will do what you want. There are a couple of other options though. First you can disable the tile fade-in and have it display immediately with something like this:

@interface NoFadeTiledLayer : CATiledLayer {
}
@end

@implementation NoFadeTiledLayer
+ (CFTimeInterval)fadeDuration {
    return 0.0;
}
@end

@implementation MyViewWithTiledLayer
+ (Class)layerClass {
    return [NoFadeTiledLayer class];
}
...
@end

Second, you can do your own pre-fetch and caching of the adjacent tiles so they're ready to go when CATileLayer calls drawLayer:inContext. I'd implement scrollViewDidScroll: and scrollViewDidZoom: to determine the adjacent tiles and levelOfDetail. Then do a cache lookup and add any not present to a pre-fetch/render queue. A background thread could service the queue and subsequent scrolls or zooms would clear and rebuild the queue. Then have drawLayer:inContext check the cache first and only fetch/render if necessary.

like image 102
John Lemberger Avatar answered Sep 30 '22 08:09

John Lemberger