Frage

I have an NSView that is drawing a custom background with an image, but whenever I press a button or programmatically edit a label, it seems to draw the background image again inside of the edited subview. I've found that making the view layer-backed in IB solves the issue, but in the larger app I'm creating, making the view layer-backed causes a ton of other issues.

I made this example app to show as clearly as possible what is happening. The second image happens after pressing the button, which programmatically edits the label text. It seems as though the background image is drawing around both the button and label together, starting at the top of the button.

the view is being drawn like this:

- (void) drawRect:(NSRect)dirtyRect {
    [[NSImage imageNamed:@"redGreenGradientBG.png"] drawInRect:dirtyRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
}

Before edit:

Before edit

After edit:

After edit

Is there any way I can fix this without making the view layer-backed?

(Sorry about the gross gradient -- I thought it would illustrate my point clearest)

War es hilfreich?

Lösung

The dirtyRect parameter that's being passed in to -drawRect: is not the entire bounding rectangle of your view, but rather the rectangle that has been marked as needing an update (ie. the "dirty" rectangle, as the name suggests).

When you press the button or edit the label, its invalidating the display state for only that subview's bounding rectangle and therefore only that rectangle is being passed as dirtyRect. So what you're seeing in those screenshots is the image being drawn into a smaller rectangle inside your view's bounding rectangle.

In your case you should just redraw the entire background in -drawRect: like this (by using self.bounds as the drawing rectangle rather than dirtyRect):

- (void)drawRect:(NSRect)dirtyRect {
    [[NSImage imageNamed:@"redGreenGradientBG.png"] drawInRect:self.bounds fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top