iOS用layer为UIButton同时添加圆角和阴影
2019-07-23 本文已影响0人
ZT_Story
UI图给出统一btn组件带有圆角阴影,通常的方式设置圆角没问题,设置阴影也没问题,但是只要用了masksToBounds浮在周边的阴影也会被一并处理掉,这也是很多小伙伴纠结的地方。
看了一些文章,好多用的是在UIButton下面同样位置大小放一个UIView来实现视觉上的阴影+圆角,功能是可以实现,但是我还是想找到看有没有别的方式。
ps:后来想简单一些,干脆用切图好了,不能这么偷懒吧。。。
新思路
既然可以用切图,那么我们可以考虑生成一个带圆角的layer并且生成一张对应尺寸的image,设置背景图然后再给button的layer设置阴影,试了一下,果然有效
这是一个带渐变色的圆角阴影按钮简单封装,大家可以参考下
// 生成一个带圆角的背景图片
CAGradientLayer *layer = [CAGradientLayer layer];
layer.frame = self.bounds;
layer.colors = @[(id)[UIColor colorWithRed:0/255.0 green:147/255.0 blue:255/255.0 alpha:1.0].CGColor, (id)[UIColor colorWithRed:0/255.0 green:118/255.0 blue:255/255.0 alpha:1.0].CGColor];
layer.locations = @[@(0), @(1.0f)];
layer.startPoint = CGPointMake(0, 0.5);
layer.endPoint = CGPointMake(1, 0.5);
layer.cornerRadius = 25;
layer.masksToBounds = YES;
UIImage *bg = [Utils imageFromLayer:layer];
// 2019-08-14 补充:发现背景图会被特殊尺寸拉伸变形,故增加UIImage的拉伸区域限制
bg = [bg resizableImageWithCapInsets:UIEdgeInsetsMake(0, 25, 0, 25) resizingMode:UIImageResizingModeStretch];
[self setBackgroundImage:bg forState:UIControlStateNormal];
// 设置按钮的阴影层
self.layer.shadowColor = [UIColor colorWithRed:0/255.0 green:118/255.0 blue:255/255.0 alpha:0.2].CGColor;
self.layer.shadowOffset = CGSizeMake(0,2);
self.layer.shadowOpacity = 1;
self.layer.shadowRadius = 6;
self.titleLabel.font = [UIFont systemFontOfSize:17];
其中工具类的方法在这里
+ (UIImage*)imageFromLayer:(CALayer *)layer {
UIGraphicsBeginImageContextWithOptions(layer.frame.size, NO, 0.0);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

2019-7-25补充
浏览到一篇文章讲的是UIView同时设置阴影和圆角,思路很好,亲测可用,在这里分享下
view的圆角、阴影、边框其实是可以共存的(注意不要设置maskToBounds为YES、并且最为关键的是borderWidth不要设置为0,
这样就可以达到圆角-borderWidth导致的圆角,和阴影共存了)
_backView.layer.shadowColor = UIColor.greenColor.CGColor;
_backView.layer.borderColor = _backView.layer.shadowColor; // 边框颜色建议和阴影颜色一致
_backView.layer.borderWidth = 0.000001; // 只要不为0就行
_backView.layer.cornerRadius = 40;
_backView.layer.shadowOpacity = 1;
_backView.layer.shadowRadius = 20;
_backView.layer.shadowOffset = CGSizeZero;