为CAShapeLayer添加阴影,使内部保持透明

时间:2013-05-08 15:21:12

标签: iphone ios objective-c core-animation

我想为一个路径添加一个发光效果,就像它们有焦点时的蓝色光晕(OS X)界面元素一样。

我使用带有(矩形)路径的CAShapeLayer:

self.borderLayer = [CAShapeLayer layer];
CGPathRef path = CGPathCreateWithRect(self.bounds, NULL);
[self.borderLayer setPath:path];
CGPathRelease(path);

最后,这给了我一个透明的UIView,周围有一个边框。 (在我的具体情况下,它是一个带有附加动画的虚线,但这对于这个特定问题并不重要)

我玩过CALayer的阴影属性,但它们总是填满整个图层。

self.borderLayer.shadowPath = self.borderLayer.path;
self.borderLayer.shouldRasterize = YES;

我想要的是只有UIViews周围的线条会掉落阴影,因此UIView的内部保持透明。

2 个答案:

答案 0 :(得分:3)

我遇到了类似的问题,看到里面的阴影,而不是发光。我用两个CALayers解决了这个问题。一,在代码中,背景为'_bg'(在我的情况下为黑色,不透明度为0.55)和白色边框。代码'_shadow'中的另一层具有清晰的背景并添加了发光效果。 _bg是_shadow图层的子视图。这是相关的代码:

_bg = [CALayer layer];
_shadow = [CALayer layer];

[self.layer insertSublayer:_shadow atIndex:0];
[_shadow addSublayer:_bg];

_bg.frame = self.bounds;
_bg.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:.55].CGColor;
_bg.cornerRadius=20.0;
_bg.borderColor=[UIColor whiteColor].CGColor;
_bg.borderWidth=2.0;

_shadow.frame=self.bounds;
_shadow.masksToBounds=NO;
_shadow.backgroundColor = [UIColor clearColor].CGColor;
_shadow.cornerRadius=3.0;
_shadow.shadowRadius=3.0;
_shadow.shadowColor=[UIColor whiteColor].CGColor;
_shadow.shadowOpacity=0.6;
_shadow.shadowOffset=CGSizeMake(0.0, 0.0);

答案 1 :(得分:2)

您可以尝试这样的事情:

    //background layer of the shadow layer
    contentViewBackgroundLayer = [CALayer layer];
    contentViewBackgroundLayer.frame = contentView.bounds;
    contentViewBackgroundLayer.backgroundColor = someColor.CGColor;
    //shadow layer
    contentViewShadowLayer = [CALayer layer];
    [contentViewShadowLayer addSublayer:contentViewBackgroundLayer];
    contentViewShadowLayer.backgroundColor = [UIColor clearColor].CGColor;
    //shadowRadius
    contentViewShadowLayer.shadowRadius = 10.0;
    contentViewShadowLayer.shadowColor = [UIColor blackColor].CGColor;
    contentViewShadowLayer.shadowOpacity = 0.5;
    contentViewShadowLayer.shadowOffset = CGSizeMake(0.0, 0.0);
    //Important!!!!  add mask to shadowLayer
    contentViewBackgroundLayer.frame = contentView.bounds;
    contentViewShadowLayer.frame = contentView.bounds;
    CGRect rect = CGRectMake(contentViewShadowLayer.bounds.origin.x - 20, contentViewShadowLayer.bounds.origin.y - 20, contentViewShadowLayer.bounds.size.width + 40, contentViewShadowLayer.bounds.size.height + 40);
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:rect];
    [path appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(0, 0, contentView.bounds.size.width, contentView.bounds.size.height)]];
    //a rectangle which is transparent surrounded by a bigger rectangle
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.fillRule = kCAFillRuleEvenOdd;
    shapeLayer.path = [path CGPath];
    contentViewShadowLayer.mask = shapeLayer;
    [contentView.layer insertSublayer:contentViewShadowLayer atIndex:0];