iOS 给layer同时添加mask和shadow

分别单独给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];

想要的效果就出来了,阴影、圆角、边框俱全:

如果你有更好的方法,欢迎留言交流。

参考: CALayer的autolayout

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;

效果如下:

image.png

参考:这篇文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容