ios 为什么masksToBounds = YES 会阻止CALayer 阴影?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3690972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why masksToBounds = YES prevents CALayer shadow?
提问by jchatard
With the following snippet, I'm adding a drop shadow effect to one my UIView. Which works pretty well. But as soon as I set the view's masksToBoundsproperty to YES. The drop shadow effect isn't rendered any more.
使用以下代码段,我向 UIView 中的一个添加了阴影效果。这很好用。但是一旦我将视图的maskToBounds属性设置为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;
Do you have any ideas on this?
你对此有什么想法吗?
回答by TheSquad
Because shadow is an effect done outside the View, and that masksToBounds set to YES will tell the UIView not to draw anything that is outside itself.
因为 shadow 是在 View 之外完成的效果,而将 maskToBounds 设置为 YES 将告诉 UIView 不要绘制任何在其自身之外的东西。
If you want a roundedCorner view with shadow I suggest you do it with 2 views:
如果您想要带阴影的圆角视图,我建议您使用 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];
回答by Philip007
It's iOS 6 now, things might have changed. TheSquad's answer don't work for me until I managed to add one more line view2.layer.masksToBounds = NO;
, otherwise shadow doesn't show. Although documentation says masksToBounds
is NO by default, my code shows the opposite.
现在是 iOS 6,事情可能已经改变了。在我设法再添加一行之前view2.layer.masksToBounds = NO;
,TheSquad 的答案对我不起作用,否则不会显示阴影。虽然文档说masksToBounds
默认情况下是 NO,但我的代码显示相反。
Here is how I make a rounded corner button with shadow, which is among the most commonly used code snippet in my app.
下面是我如何制作带阴影的圆角按钮,这是我的应用程序中最常用的代码片段之一。
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];
EDIT
编辑
If views need to be animated or scrolled, masksToBounds = YES
tax performance significantly, which means animation will probably get stuttered. To get rounded corner and shadow AND smooth animation or scrolling, use following code instead:
如果视图需要动画或滚动,masksToBounds = YES
则会显着降低性能,这意味着动画可能会卡顿。要获得圆角和阴影以及平滑的动画或滚动,请改用以下代码:
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];
回答by Kushal Ashok
This is the Swift 3 and IBDesignable version of the answer posted by @TheSquad.
这是@TheSquad 发布的答案的 Swift 3 和 IBDesignable 版本。
I used the same concept while making changes in the storyboard file. First I moved my targetView(the one which requires corner radius and shadow) inside a new containerView. Then I added the following lines of code (Reference: https://stackoverflow.com/a/35372901/419192) to add some IBDesignable attributes for UIView Class:
我在故事板文件中进行更改时使用了相同的概念。首先,我将targetView(需要圆角半径和阴影的那个)移动到一个新的containerView 中。然后我添加了以下代码行(参考: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
}
}
After adding this code, I went back to the storyboard and on selecting my containerViewI could now find a new set of attributes in the attributes inspector:
添加此代码后,我回到故事板并选择我的containerView我现在可以在属性检查器中找到一组新属性:
Other than adding values for these attributes as per my choice, I also added a corner radius to my targetViewand set the masksToBounds property as true.
除了根据我的选择为这些属性添加值之外,我还向我的targetView添加了一个角半径并将 maskToBounds 属性设置为 true。
I hope this helps :)
我希望这有帮助 :)
回答by Fangming
Swift 3.0 version with StoryBoard
带有 StoryBoard 的 Swift 3.0 版本
The same idea with @TheSquad. Create a new view under the actual view and add shadow to the lower view.
与@TheSquad 相同的想法。在实际视图下创建一个新视图,并在下面的视图中添加阴影。
1. Create a view under the actual view
1.在实际视图下创建视图
Drag a UIView
to StoryBoard with same constraint as your target view. Check clip to bound for the target view. Also make sure the new view is listed before the target view so that the target view will cover the new view.
将 aUIView
拖到与目标视图具有相同约束的 StoryBoard。检查要绑定到目标视图的剪辑。还要确保新视图列在目标视图之前,以便目标视图覆盖新视图。
2. Now link the new view to your code add add shadow on it
2.现在将新视图链接到您的代码添加阴影
This is just a sample. You can do whatever way you want here
这只是一个示例。你可以在这里做任何你想做的事
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
回答by salocinx
I also had drastic performance issues with shadows and rounded corners. Instead of using the shadowPath part, I used the following lines which perfectly solved the performance hit:
我在阴影和圆角方面也遇到了严重的性能问题。我没有使用 shadowPath 部分,而是使用以下几行完美解决了性能问题:
self.layer.shouldRasterize = YES;
self.layer.rasterizationScale = UIScreen.mainScreen.scale;
回答by Svitlana
Here is one of the solutions:
这是其中一种解决方案:
@IBOutlet private weak var blockView: UIView! {
didSet {
blockView.backgroundColor = UIColor.white
blockView.layer.shadowColor = UIColor.black.cgColor
blockView.layer.shadowOpacity = 0.5
blockView.layer.shadowOffset = CGSize.zero
blockView.layer.cornerRadius = 10
}
}
@IBOutlet private weak var imageView: UIImageView! {
didSet {
imageView.layer.cornerRadius = 10
imageView.layer.masksToBounds = true
imageView.layer.shouldRasterize = true
}
}