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;