使用setShadow:为NSView添加阴影效果

3

我正在尝试为自定义的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
在回答问题之前,先提出几点注意事项:
  • 在普通的 NSView 上不需要调用 drawRect:super 实现。默认的实现什么也不做。
  • 应该使用 [self bounds] 作为填充矩形,而不是 dirtyRectdirtyRect 参数用于指示需要绘制的视图部分,并仅用于绘制优化。
  • 你正在泄漏 dropShadow 对象。创建后应该调用 autorelease 或在调用 setShadow: 后调用 release

阴影未显示的原因有两个。首先,为了使基于层的视图显示阴影,视图的父视图也必须是基于层的。

其次,你设置了阴影的颜色但没有设置它的其他参数:

- (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;
}

5
如果你没有使用ARC(自动引用计数)编译pcperini的方法文件,那么“dropShadow泄漏”才会被认定为“泄漏”。现在ARC已经广泛应用,启用ARC后调用release或autorelease将导致编译错误。请注意不要改变原意。 - ctpenrose

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接