PDA

View Full Version : Zooming a UIScrollView without a CATiledLayer




kainjow
Jul 8, 2010, 06:07 PM
I've been trying to figure out how to zoom a UIScrollView without using CATiledLayer. Almost every example I've found and Apple's documentation says you should use CATiledLayer since it handles the automatic zooming for you and you just need to draw your content like normal via the layer's delegate. If you don't use CATiledLayer you get simply a blurred image of your layer/view.

However if you try to add sublayers to CATiledLayer, you don't get the nice sharpened scaling automatically (CAShapeLayer does work though). The other problem with CATiledLayer is you have very little control over it.

Lots of various people have played around with altering the transform which I didn't have much success with (could be due to iOS 4 changes?).

However, I think I have found a solution which would make sense based on how Apple's CATiledLayer works and CAShapeLayer's documentation. You just need to redraw the layer's image at the scaled value into a CGImage (CGBitmapContext) and set that as the layer's contents.

It's working well right now in the simulator, but I feel like there should be a better way to go about it. What do you guys think? I can post a sample project.



althecoug
Jul 9, 2010, 04:58 PM
Hi kainjow

Please post a project. Also, do you have a project that does zooming a UIScrollView with a CATiledLayer using CG drawing elements (e.g., line art, text) (as opposed to an image)? I have yet to find an sample code that does this combination correctly.

Thanks

a9702466
Jul 24, 2010, 02:51 PM
Beware! Using the contents property always needs a lot of memory for higher zoomscales. This Memory is aquired by the View and you cannot avoid this only by Tiling the content. It seem that the layer allocates memory for an images of the current zoomScale and draws the given image in it. It doesn't use the image directly.

kainjow
Jul 24, 2010, 04:50 PM
Also, do you have a project that does zooming a UIScrollView with a CATiledLayer using CG drawing elements (e.g., line art, text) (as opposed to an image)? I have yet to find an sample code that does this combination correctly.

There's nothing special to it. Just draw into the layer's context via the delegate method (overriding the CALayer method may also work). It will get properly scaled for you automatically. However if you want to *not* draw scaled, you need to apply a transform that essentially cancels the existing zoom transform and then apply the scale to your drawing manually. This is what I'm currently doing along with CATiledLayer to better handle how the zoomed drawing renders. I may post a sample later.

Beware! Using the contents property always needs a lot of memory for higher zoomscales. This Memory is aquired by the View and you cannot avoid this only by Tiling the content. It seem that the layer allocates memory for an images of the current zoomScale and draws the given image in it. It doesn't use the image directly.

yea that is the problem when rolling your own without CATiledLayer. I decided to just use CATiledLayer for the time being but may end up having to roll my own version that provides greater control of how and when the tiles get generated and cached.