0

i would like to be able to set the background of my views. Currently i try to do it by overriding -(void)drawRect:(NSRect)dirtyRect like suggested here, so my custom view looks like this:

@implementation ViewWithBackgroundColor

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // ...
    }

    return self;
}

- (void)dealloc
{
    [super dealloc];
}

- (void)drawRect:(NSRect)dirtyRect
{
    [super drawRect:dirtyRect];

    [[NSColor greenColor] setFill];
    NSRectFill(dirtyRect);
}

@end

when i hit build an run the view appears in the default grey background, but when i resize the window the view appears in the desired green color.

does anybody knows what i am missing? I am not sure if it is relevant, but the view is stored in a nib. I already tried to call setNeedsDisplay:YES in awakeFromNib, but it did not help.

thx in advance, Yevgeniy

Community
  • 1
  • 1
Yevgeniy
  • 2,614
  • 1
  • 19
  • 26

2 Answers2

2

There are some issues with your ‑drawRect: method. Firstly, you don't need to (and shouldn't) call super's implementation of ‑drawRect: unless there is a very specific reason to do so. The default implementation of ‑drawRect: does nothing, so in this case it's just a wasted message but you should get out of the habit.

Secondly, when drawing something that covers the whole view, you should normally ignore the dirty rect that's passed in, and draw the background by using [self bounds] as the rect passed to NSRectFill().

If you're linking against the 10.6 SDK or above, you can just set the backgroundColor property of the view instead of drawing the background yourself. Earlier SDKs don't support this property.

Rob Keniger
  • 45,830
  • 6
  • 101
  • 134
  • i thought i have to call _[super drawRect:dirtyRect]_ to get my subviews drawn, but it seems to be unnecessary - thx. – Yevgeniy Jul 10 '11 at 07:40
  • setting background like [self setBackground:aColor] works - thx. I recall from former versions, that NSView did not respond to setBackground. – Yevgeniy Jul 10 '11 at 07:43
  • i just noticed that setting backgroundColor with _[self setBackgroundColor:aColor]_ worked only because i implemented it earlier and forgot about it. After i removed my own property(backgroundColor) NSView stopped responding to _setBackgroundColor_ although i link against 10.6. My original problem was related to the fact that i was using [NSColor _sourceListBackgroundColor] as my color (not green, like in the above example). The code i posted works well with colors like [NSColor greenColor]. Thx Rob and everybody anyway. – Yevgeniy Jul 10 '11 at 20:21
  • The view needs to be layer-backed and then you would call `[[myView layer] setBackgroundColor:myColor]` as the `backgroundColor` property is on the layer, not the NSView. – Andrew Oct 29 '12 at 23:14
  • Calling super's implementation of an overridden method is NOT a bad habit; in fact, it makes your code more future-proof. If Apple decides to change the implementation of `drawRect:`, then you won't need to make any changes. – T Blank Jul 03 '14 at 18:02
-4

Why don't you try setting the backgroundColor property to [NSColor greenColor] at init self.backgroundColor = [NSColor greenColor];

jglievano
  • 501
  • 4
  • 21
  • NSViews don't have a backgroundColor property. You may be thinking of UIView (iOS). – Olie Feb 29 '12 at 00:38