为什么masksToBounds = YES防止CALayer阴影?

用下面的代码片段,我给一个UIView添加了阴影效果。 哪个工作得很好。 但只要我把视图的masksToBounds属性设置为YES 。 投影效果不再呈现。

self.myView.layer.shadowColor = [[UIColor blackColor] CGColor]; self.myView.layer.shadowOpacity = 1.0; self.myView.layer.shadowRadius = 10.0; self.myView.layer.shadowOffset = CGSizeMake(0.0f, 0.0f); self.myView.layer.cornerRadius = 5.0; self.myView.layer.masksToBounds = YES; // <-- This is causing the Drop shadow to not be rendered UIBezierPath *path = [UIBezierPath bezierPathWithCurvedShadowForRect:self.myView.bounds]; self.myView.layer.shadowPath = path.CGPath; self.myView.layer.shouldRasterize = YES; 

你有什么想法吗?

因为阴影是在视图之外完成的效果,并且将masksToBounds设置为YES会告诉UIView不要绘制任何超出其自身的东西。

如果你想要一个带有阴影的roundedCorner视图,我build议你用2个视图来做:

 UIView *view1 = [[UIView alloc] init]; UIView *view2 = [[UIView alloc] init]; view1.layer.cornerRadius = 5.0; view1.layer.masksToBounds = YES; view2.layer.cornerRadius = 5.0; view2.layer.shadowColor = [[UIColor blackColor] CGColor]; view2.layer.shadowOpacity = 1.0; view2.layer.shadowRadius = 10.0; view2.layer.shadowOffset = CGSizeMake(0.0f, 0.0f); [view2 addSubview:view1]; [view1 release]; 

现在是iOS 6,事情可能已经改变了。 直到我设法添加一行viewSlayer的答案不适用于我view2.layer.masksToBounds = NO; ,否则影不显示。 虽然文档说,默认情况下, masksToBounds是NO,但是我的代码显示的是相反的。

下面是我如何制作带有阴影的圆angularbutton,这是我的应用程序中最常用的代码段。

 button.layer.masksToBounds = YES; button.layer.cornerRadius = 10.0f; view.layer.masksToBounds = NO; // critical to add this line view.layer.cornerRadius = 10.0f; view.layer.shadowOpacity = 1.0f; // set shadow path to prevent horrible performance view.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:_button.bounds cornerRadius:10.0f].CGPath; [view addSubview:button]; 

编辑

如果视图需要animation或滚动, masksToBounds = YES税收性能显着,这意味着animation可能会结结巴巴。 要获得圆angular和阴影,平滑animation或滚动,请使用以下代码:

 button.backgroundColor = [UIColor clearColor]; button.layer.backgroundColor = [UIColor redColor].CGColor; button.layer.masksToBounds = NO; button.layer.cornerRadius = 10.0f; view.layer.shadowOpacity = 0.5f; view.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:_button.bounds cornerRadius:10.0f].CGPath; view.layer.shadowOffset = CGSizeMake(0.0f, 4.0f); view.layer.shadowRadius = 2.0f; view.layer.masksToBounds = NO; view.layer.cornerRadius = 10.0f; [view addSubview:button]; 

我也有阴影和圆angular剧烈的性能问题。 我没有使用shadowPath部分,而是使用以下几行完美解决了性能问题:

 self.layer.shouldRasterize = YES; self.layer.rasterizationScale = UIScreen.mainScreen.scale; 

这是@TheSquad发布的答案的Swift 3和IBDesignable版本。

我在故事板文件中进行更改时使用了相同的概念。 首先,我在新的containerView中移动了我的targetView (需要angular半径和阴影的那个)。 然后,我添加了以下几行代码(参考: https ://stackoverflow.com/a/35372901/419192)为UIView类添加一些IBDesignable属性:

 @IBDesignable extension UIView { /* The color of the shadow. Defaults to opaque black. Colors created * from patterns are currently NOT supported. Animatable. */ @IBInspectable var shadowColor: UIColor? { set { layer.shadowColor = newValue!.cgColor } get { if let color = layer.shadowColor { return UIColor(cgColor: color) } else { return nil } } } /* The opacity of the shadow. Defaults to 0. Specifying a value outside the * [0,1] range will give undefined results. Animatable. */ @IBInspectable var shadowOpacity: Float { set { layer.shadowOpacity = newValue } get { return layer.shadowOpacity } } /* The shadow offset. Defaults to (0, -3). Animatable. */ @IBInspectable var shadowOffset: CGPoint { set { layer.shadowOffset = CGSize(width: newValue.x, height: newValue.y) } get { return CGPoint(x: layer.shadowOffset.width, y:layer.shadowOffset.height) } } /* The blur radius used to create the shadow. Defaults to 3. Animatable. */ @IBInspectable var shadowRadius: CGFloat { set { layer.shadowRadius = newValue } get { return layer.shadowRadius } } /* The corner radius of the view. */ @IBInspectable var cornerRadius: CGFloat { set { layer.cornerRadius = newValue } get { return layer.cornerRadius } } 

添加这段代码后,我回到故事板,select我的containerView ,现在我可以在属性检查器中find一组新的属性:

在这里输入图像描述

除了根据我的select为这些属性添加值外,我还为我的targetView添加了一个angular半径,并将masksToBounds属性设置为true。

我希望这有帮助 :)

Swift 3.0版本与StoryBoard

与@TheSquad相同的想法。 在实际视图下创build一个新视图,并向下视图添加阴影。

1.在实际视图下创build一个视图

拖动一个UIView到与目标视图相同约束的StoryBoard。 检查剪辑以绑定目标视图。 还要确保新视图在目标视图之前列出,以便目标视图将覆盖新视图。

在这里输入图像描述

2.现在将新视图链接到你的代码上,在其上添加阴影

这只是一个例子。 你可以做任何你想在这里的方式

 shadowView.layer.masksToBounds = false shadowView.layer.shadowColor = UIColor.red.cgColor shadowView.layer.shadowOpacity = 0.5 shadowView.layer.shadowOffset = CGSize(width: -1, height: 1) shadowView.layer.shadowRadius = 3 shadowView.layer.shadowPath = UIBezierPath(rect: coverImage.bounds).cgPath shadowView.layer.shouldRasterize = true