Image inside NSScrollView drawing on top of other views

亡梦爱人 提交于 2019-12-10 10:59:35

问题


I have a custom NSView that lives inside of a NSScrollView that is in a NSSplitView. The custom view uses the following drawing code:

- (void)drawRect:(NSRect)dirtyRect {
    NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
    [ctx saveGraphicsState];

    // Rounded Rect
    NSRect rect = [self bounds];
    NSRect pathRect = NSMakeRect(rect.origin.x + 3, rect.origin.y + 6, rect.size.width - 6, rect.size.height - 6);
    NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:pathRect cornerRadius:kDefaultCornerRadius];

    // Shadow
    [NSShadow setShadowWithColor:[NSColor colorWithCalibratedWhite:0 alpha:0.66]
                      blurRadius:4.0
                          offset:NSMakeSize(0, -3)];     
    [[NSColor colorWithCalibratedWhite:0.196 alpha:1.0] set];
    [path fill];
    [NSShadow clearShadow];


    // Background Gradient
    NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:[UAColor darkBlackColor] endingColor:[UAColor lightBlackColor]];
    [gradient drawInBezierPath:path angle:90.0];
    [gradient release];


    // Image
    [path setClip];
    NSRect imageRect = NSMakeRect(pathRect.origin.x, pathRect.origin.y, pathRect.size.height * kLargeImageRatio, pathRect.size.height);
    [self.image drawInRect:imageRect
                  fromRect:NSZeroRect
                 operation:NSCompositeSourceAtop
                  fraction:1.0];

    [ctx restoreGraphicsState];

    [super drawRect:dirtyRect];
}

I have tried every different type of operation but the image still draws on top of the other half of the NSSplitView like so:

…instead of drawing under the NSScrollView. I think this has to do with drawing everything instead of the dirtyRect only, but I don't know how I could edit the image drawing code to only draw the part of it that lies in the dirtyRect. How can I either prevent it from drawing on top, or only draw the dirty rect for this NSImage?


回答1:


I finally got it. I don't know if it is optimal yet, but I will find out when doing performance testing. I just had to figure out the intersection of the image rect and the dirty rect using NSIntersectionRect, then figuring out which subpart of the NSImage to draw for the drawInRect:fromRect:operation:fraction: call.

Here is the important part:

    NSRect imageRect = NSMakeRect(pathRect.origin.x, pathRect.origin.y, pathRect.size.height * kLargeImageRatio, pathRect.size.height);
    [self.image setSize:imageRect.size];

    NSRect intersectionRect = NSIntersectionRect(dirtyRect, imageRect);
    NSRect fromRect = NSMakeRect(intersectionRect.origin.x - imageRect.origin.x,
                                 intersectionRect.origin.y - imageRect.origin.y,
                                 intersectionRect.size.width,
                                 intersectionRect.size.height);
    [self.image drawInRect:intersectionRect
                  fromRect:fromRect
                 operation:NSCompositeSourceOver
                  fraction:1.0];


来源:https://stackoverflow.com/questions/5099881/image-inside-nsscrollview-drawing-on-top-of-other-views

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!