NSView Drop Shadow Используя setShadow: - PullRequest
3 голосов
/ 29 января 2012

Я пытаюсь создать тень для пользовательского подкласса NSView.

Пока мне удалось:

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        NSShadow *dropShadow = [[NSShadow alloc] init];
        [dropShadow setShadowColor: [NSColor redColor]];

        [self setWantsLayer: YES];
        [self setShadow: dropShadow];
    }

    return self;
}

- (void)drawRect:(NSRect)dirtyRect
{
    [[NSColor blueColor] setFill];
    NSRectFill(dirtyRect);

    [super drawRect: dirtyRect];
}

, который отображает только синий квадрат (т.е. без тени).

Я настраиваю тень в нужном месте? Соблюдаю ли я все необходимые требования для использования setShadow:?

1 Ответ

19 голосов
/ 29 января 2012

Несколько замечаний, прежде чем ответить на вопрос:

  • Вам не нужно вызывать super реализацию drawRect: на ванили NSView.Реализация по умолчанию ничего не делает.
  • Вы должны использовать [self bounds] в качестве прямоугольника заполнения, а не dirtyRect.Параметр dirtyRect используется для указания части вида, которая требует рисования, и используется только для оптимизации рисования.
  • Вы пропускаете объект dropShadow.Вы должны либо вызвать autorelease на нем после создания, либо вызвать release на нем после вызова setShadow:.

Причина, по которой тень не отображается, имеет две стороны.Во-первых, для того, чтобы представления на основе слоя отображали тень, суперпредставление представления также должно быть на уровне слоя.

Во-вторых, вы устанавливаете цвет тени, но не другие параметры:

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        NSShadow *dropShadow = [[NSShadow alloc] init];
        [dropShadow setShadowColor:[NSColor redColor]];
        [dropShadow setShadowOffset:NSMakeSize(0, -10.0)];
        [dropShadow setShadowBlurRadius:10.0];

        [self setWantsLayer: YES];
        [self setShadow: dropShadow];

        [dropShadow release];
    }

    return self;
}
...