iOS用layer為UIButton同時添加圓角和陰影

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;

點擊查看原文章

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。