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

我想在路径上添加一个发光效果,就像它们具有焦点时的蓝色光晕(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的内部保持透明。

我遇到了类似的问题,看到里面的阴影,而不是发光。 我用两个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); 

你可以尝试这样的事情:

  //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];