3

I'm very confused, why does the following code work if I add it to awakeFromNib or initWithFrame:, but doesn't work if I add it to drawRect: or call it directly?

self.layer.cornerRadius = CGRectGetWidth(self.bounds) / 2.0f;
self.layer.shadowColor = [UIColor blackColor].CGColor;
self.layer.shadowRadius = 3;
self.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
self.layer.shadowOpacity = 0.75f;

For programatically created buttons, where should I add this method to? The button might be created with just init and size changed later via constraints.

Specification: By working, I mean the button will be rounded (circle if aspect ratio is 1:1) with drop shadow. By not working, I mean it'll remain a square.

Lord Zsolt
  • 6,492
  • 9
  • 46
  • 76
  • Why would you call it from `drawRect`? You override that method to draw and not think. – trojanfoe May 15 '15 at 12:18
  • `For programatically created buttons, where should I add this method to? The button might be created with just init and size changed later via constraints.` - This is why. And also, because I don't know where else to call it :) – Lord Zsolt May 15 '15 at 12:18
  • `drawRect:` are called after `init...` & `awakeFromNib` and till the time your window's or view's layers are already created. You again need to update them. – Anoop Vaidya May 15 '15 at 12:21
  • Ok, but this still doesn't answer my question of where should I put it for buttons created with init + constraints. – Lord Zsolt May 15 '15 at 12:25
  • @LordZsolt: I believe my last sentence gives a hint, isn't it. Whenever you draw something new, you need to `[setNeedDisplay:YES]`... – Anoop Vaidya May 15 '15 at 12:32

1 Answers1

1

Check out the detailed description in the Apple Docs, but essentially it's because you're setting your layer configurations (cornerRadius, shadow, etc.) in the middle of the draw cycle when you should have completed this before the draw cycle began.

From the drawRect: documentation:

By the time this method is called, UIKit has configured the drawing environment appropriately for your view and you can simply call whatever drawing methods and functions you need to render your content.

Other functions, like awakeFromNib: or initWithFrame: occur before the draw cycle, meaning your configurations will be taken into account before they are rendered on screen. By comparison, drawRect: assumes these basic configurations are already set and just works on rendering what you've specified on screen.

Vivek Molkar
  • 3,910
  • 1
  • 34
  • 46
sharpnado
  • 21
  • 4