Prevent NSButtonCell image from drawing outside of its containing NSScrollView
I have asked (and answered) a very similar question before. That question was able to be solved because I knew the dirtyRect
, and thus, knew where I should draw the image. Now, I am seeing the same behavior with an subclassed NSButtonCell
:
In my subclass, I am simply overriding the drawImage:withFrame:inView
method to add a shadow.
- (void)drawImage:(NSImage *)image withFrame:(NSRect)frame inView:(NSView *)controlView {
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
[ctx saveGraphicsState];
// Rounded Rect
NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:frame cornerRadius:kDefaultCornerRadius];
NSBezierPath *shadowPath = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 0.5, 0.5) cornerRadius:kDefaultCornerRadius]; // prevents the baground showing through the image corner
// Shadow
NSColor *shadowColor = [UAColor colorWithCalibratedWhi开发者_开发技巧te:0 alpha:0.8];
[NSShadow setShadowWithColor:shadowColor
blurRadius:3.0
offset:NSMakeSize(0, -1)];
[[NSColor colorWithCalibratedWhite:0.635 alpha:1.0] set];
[shadowPath fill];
[NSShadow clearShadow];
// Background Gradient in case image is nil
NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:[UAColor grayColor] endingColor:[UAColor lightGrayColor]];
[gradient drawInBezierPath:shadowPath angle:90.0];
[gradient release];
// Image
if (image) {
[path setClip];
[image drawInRect:frame fromRect:CGRectZero operation:NSCompositeSourceAtop fraction:1.0];
}
[ctx restoreGraphicsState];
}
It seems all pretty standard, but the image is still drawing outside of the containing scrollview bounds. How can I avoid this?
You shouldn't call -setClip
on an NSBezierPath
unless you really mean it. Generally you want ‑addClip
, which adds your clipping path to the set of current clipping regions.
NSScrollView
works by using its own clipping path and you're blowing that path away before drawing your image.
This tripped me up for a long time too.
精彩评论