Why masksToBounds = YES prevents CALayer shadow? Why masksToBounds = YES prevents CALayer shadow? ios ios

Why masksToBounds = YES prevents CALayer shadow?


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.

If you want a roundedCorner view with shadow I suggest you do it with 2 views:

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


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.

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 lineview.layer.cornerRadius = 10.0f;view.layer.shadowOpacity = 1.0f;// set shadow path to prevent horrible performanceview.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:

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


Swift 3.0 version with StoryBoard

The same idea with @TheSquad. Create a new view under the actual view and add shadow to the lower view.

1. Create a view under the actual view

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.

enter image description here

2. Now link the new view to your code add add shadow on it

This is just a sample. You can do whatever way you want here

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