如何为View(包含子View)同时添加圆角和阴影效果

想要为UIView添加一个圆角需要设置layer层的masksToBounds为YES(不设置的话子视图超出圆角的部分会显示出来),如果同时我们为按钮添加阴影效果的话,此时阴影效果由于masksToBounds的值为YES也无法显示出来。

我们可以考虑将UIView的子视图也设置为圆角,将父视图的masksToBounds设置为NO,子视图的masksToBounds设置为YES。

比如我们想为如下的View(包含一个titleView和一个contentView)添加圆角和阴影

  1. 为父视图添加圆角和阴影效果,masksToBounds设置为NO
1
2
3
4
5
6
self.layer.cornerRadius = 8.0;
self.layer.shadowRadius = 8.0;
self.layer.shadowColor = [UIColor grayColor].CGColor;
self.layer.shadowOffset = CGSizeMake(0, 7);
self.layer.shadowOpacity = 0.15;
self.layer.masksToBounds = NO;
  1. 为上半部分View添加左上和右上的圆角,masksToBounds设置为YES
1
2
3
4
5
6
7
8
9
10
11
12
CGRect topCornerRect =
CGRectMake(self.titleView.bounds.origin.x, self.titleView.bounds.origin.x, self.bounds.size.width, 24);
UIBezierPath *titleViewMaskPath = [UIBezierPath bezierPathWithRoundedRect:topCornerRect
byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
cornerRadii:CGSizeMake(8, 8)];
//创建 layer
CAShapeLayer *titleViewMaskLayer = [[CAShapeLayer alloc] init];
titleViewMaskLayer.frame = topCornerRect;
//赋值
titleViewMaskLayer.path = titleViewMaskPath.CGPath;
self.titleView.layer.mask = titleViewMaskLayer;
self.titleView.layer.masksToBounds = YES;
  1. 为下半部分View添加左上和右上的圆角,masksToBounds设置为YES
CGRect bottomCornerRect = CGRectMake(self.blockSuperView.bounds.origin.x, self.blockSuperView.bounds.origin.x,
                                     self.bounds.size.width, self.bounds.size.height - 24);
UIBezierPath *blockSuperViewMaskPath =
    [UIBezierPath bezierPathWithRoundedRect:bottomCornerRect
                          byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight
                                cornerRadii:CGSizeMake(8, 8)];
//创建 layer
CAShapeLayer *blockSuperViewMaskLayer = [[CAShapeLayer alloc] init];
blockSuperViewMaskLayer.frame = bottomCornerRect;
//赋值
blockSuperViewMaskLayer.path = blockSuperViewMaskPath.CGPath;
self.blockSuperView.layer.mask = blockSuperViewMaskLayer;
self.blockSuperView.layer.masksToBounds = YES;

最终显示效果: