3

I'm working on an iPhone app which will be displaying large scrollable and zoomable surface containing a grid of pictures and text labels over them. I need to be able to change the position of pictures individually and control the opacity level of labels. I tried to accomplish these goals by using UIScrollView and Core Animation.

The subview of UIScrollView contains two main sublayers: one for displaying pictures and one for the labels. Pictures are CALayers with their contents property set to CGImage and they are added as sublayers to the pictures layer. Labels are CATextLayers and they are sublayers of the second layer. Transparency of the labels layer changes depending on the zoom scale of the scroll view.

And here is the problem: everything works fine when the labels are fully opaque or fully transparent, but when they are semitransparent scrolling starts to be jerky and FPS drops to about 35. Obviously blending of these layers slows everything down, but I couldn't find a way to fix it. I will appreciate any ideas on how to improve the performance in this situation. Maybe there is a better way to draw text labels than using CATextLayer?

qbba.lys
  • 73
  • 6

2 Answers2

0

Is it possible for you to merge the two "main layers" of your UIScrollView into one? Also, is it possible for you to add layers directly to UIScrollView's layer instead of adding additional ones?

I find that I get huge performance wins by reducing the number of layers that exist for the sole purpose of containing other layers.

Dany Joumaa
  • 2,030
  • 6
  • 30
  • 45
  • I keep the labels on the separate layer so I can adjust transparency of all of them at once. But I'll try to add the pictures directly to the layer of the scrollview's subview and see if that helps, thanks for advice. – qbba.lys Aug 03 '13 at 18:11
  • Ah, I see. At the end of the day it comes down to trying different things, because performance issues are always situational. However, I would guess that Objective C fast enumeration + setting alphas individually is faster than having a container layer and changing the opacity of that (you'd have one less layer to blend). Anyway, let me know if you have any other questions. – Dany Joumaa Aug 03 '13 at 19:59
-1

One solution is to add a shadow to the most background layers of both image layer and text layer.

There are number of shadow properties that you can tweak i.e. shadowPath, shadowColor, shadowOffset and shadowRadius - set each of them, don't miss any. Also set yourlayer.masksToBounds = NO.

Do not forget to add yourlayer.shouldRasterize = YES because this will have better performance impact.

Nirav Bhatt
  • 6,940
  • 5
  • 45
  • 89
  • Why would adding a shadow when he doesn't even need shadows increase performance? And how do you know shouldRasterize would improve performance in this scenario? He may be invalidating the layers for whatever reason as he zooms in. – Dany Joumaa Aug 03 '13 at 14:17
  • shadow (even of width such as 0.01) removes jagged edges, which maybe the case as OP is describing it as "starts to be jerky". I have used shadow to smoother things up. Rasterizing has better effect on performance. As far as you are caching each layer that will be redrawn upon scrolling - it is good. See this - http://stackoverflow.com/questions/11521959/uiview-self-layer-shouldrasterize-yes-and-performance-issues. Be careful before downvoting man. – Nirav Bhatt Aug 03 '13 at 14:57
  • By "jerky" I meant low FPS while scrolling, sorry if it wasn't clear. I was experimenting with `shouldRasterize` but unfortunately it didn't help in my case. Rasterizing individual pictures and/or labels doesn't make any difference, and rasterizing the whole view makes scrolling even slower and causes flickering as parts of the bitmap are being displayed. – qbba.lys Aug 03 '13 at 18:13