iOS 同时显示圆角(部分)、阴影和边框
在 iOS 开发中,让View显示圆角和阴影以及边框
方法1:系统的UIView
UIView *v=[[UIView alloc]initWithFrame:CGRectMake(100, 200, viewWidth, viewHeight)];
v.backgroundColor=[UIColor yellowColor];
// v.layer.masksToBounds=YES;//这行去掉才行
v.layer.cornerRadius=cornerRadius;
v.layer.shadowColor=[UIColor redColor].CGColor;
v.layer.shadowOffset=CGSizeMake(0, 0);
v.layer.shadowOpacity=1;
v.layer.shadowRadius=5;
v.layer.borderWidth = 2;
v.layer.borderColor = [UIColor blueColor].CGColor;
[self.view addSubview:v];
UIView的缺点: 只能v.layer.masksToBounds=NO,v.clipsToBounds = NO;
即子view如果超过View的边界不会裁剪,也不能只显示部分圆角
方法2:
定义一个新的View,重写view的layoutSubviews方法
//核心代码,设置部分圆角
-(void)layoutSubviews{
[super layoutSubviews];
//cornerType可以由外界传入,是UIRectCorner枚举类型变量
//radius可以由外界传入
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:cornerType cornerRadii:CGSizeMake(radius,radius)];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.frame = self.bounds;
layer.path = path.CGPath;
self.layer.mask = layer;
//设置border边框,也可以部分圆角
//_borderWidth和_borderColor由外界传入
// 这个地方的path和自定义view的layer的path相同
CAShapeLayer* borderLayer = [CAShapeLayer layer];
borderLayer.lineWidth = _borderWidth;
borderLayer.path = path.CGPath;
borderLayer.fillColor = [UIColor clearColor].CGColor;
borderLayer.strokeColor = _borderColor;
borderLayer.frame = self.bounds;
[self.layer addSublayer:borderLayer];
}
使用同方法1,可以设置部分圆角,但不能显示阴影(受mask的影响,就算设置了layer的shadow属性也会被layoutSubviews方法中的代码覆盖)
方法3:
定义一个新的View,view的layer属性类型用CAShapeLayer代替CALayer
#import "RoundCornerView.h"
@implementation RoundCornerView
//核心代码,view的layer属性类型用CAShapeLayer代替CALayer
+ (Class)layerClass {
return [CAShapeLayer class];
}
//重新init方法,背景颜色赋一个默认值
- (instancetype)init
{
self = [super init];
if (self) {
if ([self.layer isKindOfClass:[CAShapeLayer class]]) {
((CAShapeLayer *)self.layer).fillColor = [UIColor clearColor].CGColor;
}
}
return self;
}
//核心代码,设置部分圆角
-(void)layoutSubviews{
[super layoutSubviews];
//UIRectCornerType可以由外界传入,是UIRectCorner枚举类型变量
//radius可以由外界传入
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTypecornerRadii:CGSizeMake(radius,radius)];
if ([self.layer isKindOfClass:[CAShapeLayer class]]) {
((CAShapeLayer *)self.layer).path = maskPath.CGPath;
}
// self.clipsToBounds = YES;//去掉这行才行
//设置border边框,也可以部分圆角
//_borderWidth和_borderColor由外界传入
// 这个地方的path和自定义view的layer的path相同
CAShapeLayer* borderLayer = [CAShapeLayer layer];
borderLayer.lineWidth = _borderWidth;
borderLayer.path = maskPath.CGPath;
borderLayer.fillColor = [UIColor clearColor].CGColor;
borderLayer.strokeColor = _borderColor;
borderLayer.frame = self.bounds;
[self.layer addSublayer:borderLayer];
}
//背景颜色不是直接赋值给view.backgroundColor
- (void)setBackgroundColor:(UIColor *)backgroundColor {
((CAShapeLayer *)self.layer).fillColor = backgroundColor.CGColor;
}
@end
然后可以随心所欲的设置阴影了,并且不受mask的影响
RoundCornerView* 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];
优点:可以只显示部分圆角,可以显示阴影
缺点:超过父View的边界不会裁剪
方法4:
可以在一个 View 里只应用一种效果,然后通过组合的方式达到效果。
层次结构:
roundCornerView:显示圆角,放在上层
shadowView: 显示阴影,放在底层
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//两个View,父View负责阴影,子View负责圆角,父View背景透明,这样叠加起来就可以既有圆角又有阴影
ShadowView *shadowView = [[ShadowView alloc] initWithFrame:CGRectMake(150, 250, viewWidth, viewHeight)];
shadowView.layer.backgroundColor = [UIColor clearColor].CGColor;
shadowView.layer.shadowColor = [UIColor blackColor].CGColor;
shadowView.layer.shadowOpacity = 1;
shadowView.layer.shadowOffset = CGSizeMake(0, 0);
shadowView.layer.shadowRadius = 5;
RoundCornerView *roundCornerView = [[RoundCornerView alloc] initWithFrame:CGRectMake(0, 0, viewWidth, viewHeight)];
roundCornerView.backgroundColor = [UIColor blueColor];
roundCornerView.radius = cornerRadius;
roundCornerView.cornerType = UIRectCornerTopLeft | UIRectCornerBottomLeft;
roundCornerView.borderWidth = borderWidth;
roundCornerView.borderColor = [UIColor blueColor].CGColor;
[self.view addSubview:shadowView];
[shadowView addSubview:roundCornerView];
}
@end
如果roundCornerView像方法2一样重写了layoutSubviews方法,那么方法4就可以显示部分圆角和阴影和边框了,而且超过父View的边界可以裁剪