If I create a subclassed UIView
and want to use a bunch of custom made content (animations via CABasicAnimation
using CAShapeLayer
s, 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?
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.
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.
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:'
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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With