Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CATiledLayer blanking tiles before drawing contents

All,

I'm having trouble getting behavior that I want from CATiledLayer. Is there a way that I can trigger the tiles to redraw without having the side-effect that their areas are cleared to white first? I've already subclassed CATiledLayer to set fadeDuration to return 0.

To be more specific, here are the details of what I'm seeing and what I'm trying to achieve:

  • I have a UIScrollView with a big content size...~12000x800. Its content view is a UIView backed by a CATiledLayer.
  • The UIView is rendered with a lot of custom-drawn lines
  • Everything works fine, but the contents of the UIView sometimes change. When that happens, I'd like to redraw the tiles as seamlessly as possible. When I use setNeedsDisplay on the view, the tiles redraw but they are first cleared to white and there's a fraction-of-a-second delay before the new content is drawn. I've already subclassed CATiledLayer so that fadeDuration is set to 0.
  • The behavior that I want seems like it should be possible...when you zoom in on the scrollview and the content gets redrawn at a higher resolution, there's no blanking before the redraw; the new content is drawn right on top of the old one. That's what I'm looking for.

Thanks; I appreciate your ideas.

Update:

Just to follow up - I realized that the tiles weren't being cleared to white before the redraw, they're being taken out entirely; the white that I was seeing is the color of the view that's beneath my CATiledLayer-backed view.

As a quick hack/fix, I put a UIImageView beneath the UIScrollView, and before triggering a redraw of the CATiledLayer-backed view I render its visible section into the UIImageView and let it show. This smooths out the redraw significantly.

If anyone has a better solution, like keeping the redraw-targeted tiles from going away before being redrawn in the first place, I'd still love to hear it.

like image 603
Greg Plesur Avatar asked Nov 10 '09 19:11

Greg Plesur


2 Answers

I've found that if you set levelsOfDetailBias and levelsOfDetail both to the same value (2 in my case), then it only redraws the tiles that are touched by my setNeedsDisplayInRect: call, as you'd hope.

However if the levelsOfDetail is different to LODB, then any calls to setNeedsDisplayInRect: redraw all the tiles.

like image 162
Chris Avatar answered Oct 12 '22 22:10

Chris


You could add another layer (possibly a CATiledLayer) behind the existing tiled layer. (Sort of a double-buffered solution.) You would call setNeedsDisplay: on the second layer from a timer that fires after a few seconds to ensure that that layer doesn't redraw at the same time as the front layer.

like image 23
lucius Avatar answered Oct 12 '22 23:10

lucius