Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is the right time to animate and add sublayers in an UIView subclass

If I create a subclassed UIView and want to use a bunch of custom made content (animations via CABasicAnimation using CAShapeLayers, custom made drawings using CGContextRef in drawRect) when is the right time to create, add and animate sublayers?

I know that I should perform custom drawings in the drawRect method (and since there is the only place when I can actually get UIGraphicsGetCurrentContext() that kinda narrows my choice down). Now I have been creating sublayers, animations and all that other non-drawing related stuff in the drawRect as well. But I'm not sure that drawRect is the best place to do those kind of activities.

I am familiar with layoutSubviews method and some other UIView methods but haven't actually implemented any of them except drawRect.

So if I repeat myself one more time - the question goes: Where to add sublayers, where to animate them and are there any tricks or catches I should be aware of?

like image 412
Majster Avatar asked Sep 24 '13 17:09

Majster


1 Answers

  1. You can create and add the layers at init, if they are permanent. If they are dynamic, layoutSubviews is better. This obviously means you need to setNeedsLayout whenever a new layer/item is required. You can mix and match as much as you want between -init and -layoutSubviews, but if I had to pick, I'd say lean toward using layoutSubviews. Don't use drawRect.

  2. You can set properties (strokeWidth, lineColor, path, etc) to a CAShapeLayer at either the time of creation or during normal execution. This includes setting a path to CAShapeLayer. Again, don't set properties in drawRect.

  3. If you want to do custom drawing on the layer you can subclass a layer and use drawRect on that layer. This can be good if the CALAyers need to be reused and extended. You can also supply a CALayerDelegate, as long as its not the UIView. See these questions: Using CALayer Delegate AND iOS: Using UIView's 'drawRect:' vs. its layer's delagate 'drawLayer:inContext:'

  4. Animation is easy, and it follows the same principles as creating and setting properties. Make sure you understand when automatic animations will be invoked and how to disable them: Disabling implicit animations in -[CALayer setNeedsDisplayInRect:] Again don't try to animate from drawRect: How to make my UIBezierPath animated with CAShapeLayer?

  5. Drawing is expensive. Animation is cheap. Using drawRect too much will cause a big performance hit to your applications. Use drawRect/setNeedsDisplay sparingly, for instance on a state change (selected/unselected). Whenever possible modify views with animations or top level properties, and don't redraw the view. Making drawRect do anything OTHER than draw could result in you calling setNeedsDisplay unnecessarily. An easy upfront optimization is to call drawRect as little as possible, or not at all.

like image 196
Saltymule Avatar answered Nov 14 '22 03:11

Saltymule