分别单独给layer设置圆角和阴影都是比较简单的,在这里就不多说了。而如果同时给layer添加mask和阴影就会有问题,因为设置mask后阴影也会被切掉。而我们需要的是他们共存,为了解决这个问题我在网上找到了以下方法:
IOS view的圆角和阴影并存
iOS how-to mask and shadow an image
如何让阴影和圆角同时实现
但是上面的方法要么就是太麻烦,要么就是不符合我们的要求,下面介绍下我给出的一种方法:
自定义view,修改其layerClass为CAShapeLayer, 代码如下:
// .h
#import <UIKit/UIKit.h>
@interface ShapeView : UIView
@end
// .m
@implementation ShapeView
+ (Class)layerClass {
return [CAShapeLayer class];
}
- (instancetype)init
{
self = [super init];
if (self) {
((CAShapeLayer *)self.layer).fillColor = [UIColor colorWithRed:0 green:1 blue:1 alpha:1.0].CGColor;
}
return self;
}
-(void)layoutSubviews{
[super layoutSubviews];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerBottomLeft cornerRadii:CGSizeMake(10,10)];
((CAShapeLayer *)self.layer).path = maskPath.CGPath;
}
- (void)setBackgroundColor:(UIColor *)backgroundColor {
((CAShapeLayer *)self.layer).fillColor = backgroundColor.CGColor;
}
@end
然后可以随心所欲的设置阴影了,并且不受mask的影响:
ShapeView* shapeView = [[ShapeView alloc] init];
shapeView.backgroundColor = [UIColor grayColor];
shapeView.layer.shadowColor = [UIColor redColor].CGColor;
shapeView.layer.shadowRadius = 5.f;
shapeView.layer.shadowOffset = CGSizeMake(0.f, 0.f);
shapeView.layer.shadowOpacity = 1.f;
shapeView.frame = CGRectMake(100, 200, 500, 100);
[self.view addSubview:shapeView];
如果再想设置border,可以用下面方法:
// 这个地方的path和自定义view的layer的path相同
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:shapeView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerBottomLeft cornerRadii:CGSizeMake(10,10)];
CAShapeLayer* borderLayer = [CAShapeLayer layer];
borderLayer.path = maskPath.CGPath;
borderLayer.fillColor = [UIColor clearColor].CGColor;
borderLayer.strokeColor = [UIColor greenColor].CGColor;
borderLayer.frame = shapeView.bounds;
[shapeView.layer addSublayer:borderLayer];
想要的效果就出来了,阴影、圆角、边框俱全:
如果你有更好的方法,欢迎留言交流。
2019.3.8 更新:添加三面阴影的方法
UIView *view = [[ShapeView alloc] init];
[self.view addSubview:view];
view.backgroundColor = [UIColor grayColor];
view.frame = CGRectMake(50, 200, 300, 200);
CGFloat shadowWidth = 7;
view.layer.masksToBounds = NO;
view.layer.shadowOffset = CGSizeMake(0, 0);
view.layer.shadowRadius = shadowWidth;
view.layer.shadowOpacity = 0.9;
view.layer.shadowColor = [UIColor redColor].CGColor;
UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:CGPointMake(0, shadowWidth)];
[path addLineToPoint:CGPointMake(0, view.bounds.size.height)];
[path addLineToPoint:CGPointMake(view.bounds.size.width, view.bounds.size.height)];
[path addLineToPoint:CGPointMake(view.bounds.size.width, shadowWidth)];
[path addLineToPoint:CGPointMake(view.bounds.size.width * 0.5, view.bounds.size.height * 0.9)];
[path closePath];
view.layer.shadowPath = path.CGPath;
效果如下:
参考:这篇文章