为什么圆角和阴影不能共存?Because shadow is an effect done outside the View, and that masksToBounds set to YES will tell the UIView not to draw everything that is outside itself.
大概意思是:阴影作用于视图外部,而圆角设置裁剪会把画在视图外面的所有东西裁掉。
解决方案1:那么我们可以在View上创建一个CALayer,制作阴影,让它位于我们需要添加阴影的圆角View下面即可:
/// 绘制阴影和圆角并存
/// 并存原理:创建一个CALayer,制作阴影,让它位于我们需要添加阴影的圆角View下面即可
- (void)drawShadowCompatibleCorner {
CALayer *subLayer = [CALayer layer];
subLayer.frame = self.contentView.frame;
subLayer.cornerRadius = 12;
subLayer.masksToBounds = NO;
subLayer.backgroundColor = SD_COLOR_THEME_GRAY.CGColor;
subLayer.shadowColor = [UIColor blackColor].CGColor;//shadowColor阴影颜色
subLayer.shadowOffset = CGSizeMake(0,0);
subLayer.shadowOpacity = 0.2;//阴影透明度,默认0
subLayer.shadowRadius = 2;//阴影半径,默认3
[self.layer insertSublayer:subLayer below:self.contentView.layer];
}
解决方案2:道理一样,如果我们已经有父子视图层级,可以让上层展示内容的View绘制圆角,下层View做阴影即可:
// 父视图绘制阴影
self.bgView.backgroundColor = nil;
self.bgView.layer.masksToBounds = NO;
self.bgView.layer.shadowOpacity = 0.1f;
self.bgView.layer.shadowOffset = CGSizeZero;
self.bgView.layer.shadowRadius = 10.f;
// 子视图绘制圆角
self.contentView.layer.cornerRadius = 12.f;
self.contentView.layer.masksToBounds = YES;
给View设置部分圆角:以前可以通过绘制图层的方式绘制部分圆角,但是必须先确定好View的frame。如果是自动布局,绘制之前必须让父类调用 layoutIfNeeded。iOS11之后,可以直接使用maskedCorners设置部分圆角。
/// 绘制部分圆角
/// @param rectCorner 圆角样式
/// @param radii 圆角
- (void)drawCornerWith:(UIRectCorner)rectCorner radii:(CGFloat)radii {
self.layer.masksToBounds = YES;
if (@available(iOS 11.0, *)) {
self.layer.cornerRadius = radii;
self.layer.maskedCorners = (CACornerMask)rectCorner;//bit位一致
} else {
// 设置路径
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:rectCorner cornerRadii:CGSizeMake(radii, radii)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
maskLayer.path = maskPath.CGPath;
self.layer.mask = maskLayer;
}
}