开发者

Prevent NSButtonCell image from drawing outside of its containing NSScrollView

开发者 https://www.devze.com 2023-02-15 11:30 出处:网络
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 beh

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:

Prevent NSButtonCell image from drawing outside of its containing NSScrollView

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号