Предотвратить рисование изображения NSButtonCell за пределами его содержащего NSScrollView

Я задал (и ответил) очень похожий вопрос перед. Этот вопрос удалось решить, потому что я знал dirtyRect и, следовательно, знал, где я должен нарисовать изображение. Теперь я вижу такое же поведение с подклассом NSButtonCell:

введите здесь описание изображения

В моем подклассе я просто переопределяю метод drawImage:withFrame:inView, чтобы добавить тень.

- (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 colorWithCalibratedWhite: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];

}

Кажется, все довольно стандартно, но изображение по-прежнему рисуется за пределами границ прокрутки. Как я могу этого избежать?


person coneybeare    schedule 08.03.2011    source источник


Ответы (1)


Вы не должны называть -setClip на NSBezierPath, если только вы действительно этого не имеете в виду. Обычно вам нужен ‑addClip, который добавляет ваш путь отсечения к набору текущих областей отсечения.

NSScrollView работает, используя свой собственный путь отсечения, и вы сбрасываете этот путь, прежде чем рисовать свое изображение.

Меня это тоже долгое время сбивало с толку.

person Rob Keniger    schedule 08.03.2011