为透明形状绘制阴影

时间:2012-05-15 20:52:14

标签: objective-c ios quartz-graphics

我想为某些形状创建一个阴影(没有导致阴影的对象)。例如,对于椭圆:

CGContextSetShadowWithColor(ctx, offset, blur, color.CGColor);
CGContextFillEllipseInRect(ctx, drawInRect);

阴影画得很好,但我希望这个形状是透明的。我尝试将填充颜色设置为清除:

CGContextSetFillColorWithColor(ctx, UIColor.clearColor.CGColor);

导致阴影也被抑制。

使用黑色阴影实现透明形状的最简单方法是什么?如果我需要做一个面具,我将如何使用Quartz?

编辑:正如第一位回答者指出的那样,这个问题含糊不清或令人困惑。我试图清除一点。

2 个答案:

答案 0 :(得分:3)

你想只看到阴影,而不是椭圆?

如果你用Quartz绘制它,这很棘手,因为Quartz使用椭圆的外观来生成阴影。如果剪掉或遮住椭圆,也会影响阴影。

一种可能性是调整阴影的偏移量和椭圆的位置,以便椭圆位于上下文的可见区域之外。例如,如果您在100 x 100位图上下文中绘图,则可以将椭圆的位置设置为{normalPosition.x - 100,normalPosition.y},并将阴影的offset.x增加100.这样,椭圆就会完全脱离上下文,但阴影将在同一个地方。 (当然,根据情况调整数学运算。)

另一种选择:如果在CALayer上使用shadowPath属性,则仅基于该路径生成阴影,而不是在图层的内容上生成阴影。根据您的情况,管理它可能比纯CG更容易。

答案 1 :(得分:1)

您可以使用剪切路径执行此操作。 EO的东西是定义绘制所有东西的外部空间和没有绘制任何东西的内部空间所必需的。

我把它变得有点复杂,因为我之后会放入一个浅红色圆圈。

- (void)drawRect:(CGRect)rect
{
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSaveGState(ctx); // store to ignore the clipping path later
    float margin = self.bounds.size.width * .1;
    CGRect ellipseRect = CGRectMake(margin, margin, self.bounds.size.width - 2*margin, self.bounds.size.height - 2*margin);

    // OUTER path is just the bounds
    CGMutablePathRef mutablePath = CGPathCreateMutable();
    CGPathRef pathRef = CGPathCreateWithRect(self.bounds, NULL);
    CGPathAddPath(mutablePath, NULL, pathRef);
    // INNER path is the same as the ellipse
    CGPathRef pathRef2 = CGPathCreateWithEllipseInRect(ellipseRect, NULL);
    CGPathAddPath(mutablePath, NULL, pathRef2);
    CGContextAddPath(ctx, mutablePath);
    CGContextEOClip(ctx);    

    CGContextSetFillColorWithColor(ctx, UIColor.greenColor.CGColor);
    CGContextSetShadowWithColor(ctx, CGSizeMake(margin/2.0f, margin/2.0f), 10, UIColor.blackColor.CGColor);
    CGContextFillEllipseInRect(ctx, ellipseRect);

    // replace the green circle for a very transparent red one just for fun
    CGContextRestoreGState(ctx);
    CGContextSetFillColorWithColor(ctx, [UIColor.redColor colorWithAlphaComponent:.1].CGColor);
    CGContextSetShadowWithColor(ctx, CGSizeZero, 0, NULL);
    CGContextFillEllipseInRect(ctx, ellipseRect);
}