Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSView with gradient fill?

Tags:

cocoa

I'm trying to fill an NSView with a gradient. when the window is in the background the gradient should have lighter colors to match the rest of the window. The code below has a lot of artifacts: When the window is first drawn it is drawn with the background colors. When the window is resized, the foreground colors are used. When the window is moved to the back, the background colors are not used as expected. Should I not be using isKeyWindow for this task?

- (void)drawRect:(NSRect)dirtyRect {

    if ([[self window] isKeyWindow]) {

        NSColor *startingColor = [NSColor colorWithCalibratedWhite:0.8 alpha:1.0];
        NSColor *endingColor = [NSColor colorWithCalibratedWhite:0.6 alpha:1.0];
        NSGradient* aGradient = [[NSGradient alloc]
                             initWithStartingColor:startingColor
                             endingColor:endingColor];
        [aGradient drawInRect:[self bounds] angle:270];

    } else {
        NSColor *startingColor = [NSColor colorWithCalibratedWhite:0.9 alpha:1.0];
        NSColor *endingColor = [NSColor colorWithCalibratedWhite:0.8 alpha:1.0];
        NSGradient* aGradient = [[NSGradient alloc]
                             initWithStartingColor:startingColor
                             endingColor:endingColor];
        [aGradient drawInRect:[self bounds] angle:270];
    }
    [super drawRect:dirtyRect];
}
like image 692
Mike T Avatar asked Aug 13 '12 06:08

Mike T


1 Answers

I think the behavior you're seeing is because the window is not necessarily redrawn as it gains or loses key status. I would try forcing an update on the window when it becomes or resigns key. Something like:

- (void) viewDidMoveToWindow
{
    if( [self window] == nil ) {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    else {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(forceUpdate)
                                                     name:NSWindowDidResignKeyNotification
                                                   object:[self window]];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(forceUpdate)
                                                     name:NSWindowDidBecomeKeyNotification
                                                   object:[self window]];
    }
}

- (void) forceUpdate
{
    [self setNeedsDisplay:YES];
}
like image 127
zpasternack Avatar answered Dec 11 '22 18:12

zpasternack