2
votes

It's best explained by these two pictures. The first picture shows an nsbutton that has not yet been hovered, the second shows the same nsbutton when I have hovered over it.

As you can see, the NSView outer bezier path seems to be drawn on the button as well, for whatever reason. The button is a normal NSButton instance, no subclass.

enter image description here

enter image description here

Here's my custom NSView :

#import "MyView.h"

@implementation MyView
- (void)drawRect:(NSRect)rect
{    
    NSBezierPath *path;

    path = [NSBezierPath bezierPathWithRect:rect];
    [[NSColor redColor] set];
    [path fill];

    rect.size.width -= 10;
    rect.size.height -= 10;
    rect.origin.x += 5;
    rect.origin.y += 5;

    path = [NSBezierPath bezierPathWithRect:rect];
    [[NSColor whiteColor] set];
    [path fill];
}

- (void)awakeFromNib
{
    NSButton *commandButton = [[NSButton alloc] initWithFrame:NSMakeRect(90, 50, 100, 18)];

    [commandButton setButtonType:NSMomentaryPushInButton];
    [commandButton setBordered:YES];
    [commandButton setTitle:@"Test!"];
    [commandButton setFont:[NSFont fontWithName:@"LucidaGrande" size:14.0]];
    [commandButton setBezelStyle:NSInlineBezelStyle];

    [self addSubview:commandButton];
}

@end
1

1 Answers

3
votes

The drawing system passes in the rectangle of the view that needs to be redrawn as the single parameter to drawRect: You're using that rectangle unconditionally for the path, path = [NSBezierPath bezierPathWithRect:rect];, assuming that this rect is always the view's full bounds rect. This is not the case. When the button is being hovered over, its frame is the portion of your view which has been invalidated and needs redrawing, and that's what rect is.

You should either test rect to make sure it's appropriate to be used for the path, or -- easier and just fine unless you're having measurable drawing-related performance issues -- always use the view's bounds for the outline path.

path = [NSBezierPath bezierPathWithRect:[self bounds]];

The drawing context is going to clip the drawing to the rect it asked for anyways.