Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom UIView drawing with layoutSubviews vs drawRect

Tags:

ios

uiview

Should the drawing of CAShapeLayers be called from drawRect() or layoutSubviews()?

According to Apple's documentation on UIViews, drawing operations should be placed in drawRect().

However this is not the case in Kevin Cathey's WWDC Session: What's New in Interface Builder (where he demonstrates the process of building a custom UIView that is accessible in Interface Builder).

During his demonstration he performs the drawing of the view in layoutSubviews, rather than drawRect.

His explanation was that:

If I were to implement drawRect, that's not going to get us the best performance; whereas, using sublayers and subviews is going to get us really good performance.

From what I've read so far on StackOverflow, it seems that overriding the drawRect() method can cause reduced performance. This is partially due setNeedsDisplay triggering manual redraws being expensive.

But looking through the Apple Documentation and real world applications. It makes sense that drawRect() should be responsible for the drawing of the View, and layoutSubviews() handling positioning.

like image 542
Chao Man Avatar asked Oct 27 '14 09:10

Chao Man


1 Answers

I would say it depends. If the size of your shape is going to be dependent on the Auto Layout system then it might be beneficial to do the drawing in Layout Subview versus Draw Rect.

First, why would layout subviews ever have better performance? Well say I have a UIView (my parent view) that is drawing a Circle View (my subview) which is using a shape layer. The size of that circle is determined by a Width and Height constraint in my Parent View. I only ever need to redraw the circle when either the width/height constraints are changed on the Parent View. This is an instance where it is beneficial to have the drawing code in Layout Subviews because I only ever need to redraw the shape layer when the constraints change. Let's see the Auto Layout cycle

  1. Update Constraints
  2. Layout Subviews
  3. Render the Views

By the time layout subviews is called we know the size of the frame we are working with and can safely perform our drawing. I know the documentation says you should use this method to just set the frame, bounds, etc. However, drawing within the frame doesn't sound unreasonable depending on the circumstances.

If the Circle View isn't dependent upon the Auto Layout system and could be changed at anytime regardless of the layout of the UI, then it would probably be more beneficial to have the drawing in draw rect so it can constantly be updated. I think this is less than an ideal situation as more UI's in iOS conform to using Auto Layout, hence the recommendation of using Layout Subviews.

like image 185
JamWils Avatar answered Sep 20 '22 17:09

JamWils