最简单的方法,是让UI提供带圆角的图片
以下几种是通过代码设置的,均可以避免触发离屏渲染,提高性能
let btn0 = UIButton(type: .custom)
btn0.frame = CGRect(x: 100, y: 60, width: 100, height: 100)
//设置圆角
btn0.layer.cornerRadius = 50
self.view.addSubview(btn0)
//设置背景图片
btn0.setImage(UIImage(named: "mouse"), for: .normal)
//裁剪
btn0.layer.masksToBounds = true
改为
let btn0 = UIButton(type: .custom)
btn0.frame = CGRect(x: 100, y: 60, width: 100, height: 100)
//设置圆角
btn0.imageView?.layer.cornerRadius = 50
self.view.addSubview(btn0)
//设置背景图片
btn0.setImage(UIImage(named: "mouse"), for: .normal)
//裁剪
btn0.imageView?.layer.masksToBounds = true
extension UIImage{
// 贝塞尔曲线
func roundedCornerImageWithCornerRadius(_ cornerRadius: inout CGFloat) -> UIImage{
let w = self.size.width
let h = self.size.height
let scale = UIScreen.main.scale
//防止圆角半径小于0,或者大于宽/高中较小的值
if cornerRadius < 0 {
cornerRadius = 0
}else if cornerRadius > min(w, h){
cornerRadius = min(w, h) / 2
}
var image: UIImage?
let imageFrame = CGRect(x: 0, y: 0, width: w, height: h)
UIGraphicsBeginImageContextWithOptions(self.size, false, scale)
UIBezierPath.init(roundedRect: imageFrame, cornerRadius: cornerRadius).addClip()
self.draw(in: imageFrame)
image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
func addMaskToBounds(_ maskBounds: CGRect, _ cornerRadius: inout CGFloat) -> UIImage{
let w = maskBounds.size.width
let h = maskBounds.size.height
let size = maskBounds.size
let scale = UIScreen.main.scale
let imageRect = CGRect(x: 0, y: 8, width: w, height: h)
if cornerRadius < 0{
cornerRadius = 0
}else if cornerRadius > min(w, h){
cornerRadius = min(w, h) / 2
}
let image = UIImage.init(named: "mouse")
UIGraphicsBeginImageContextWithOptions(size, false, scale)
UIBezierPath.init(roundedRect: imageRect, cornerRadius: cornerRadius).addClip()
image?.draw(in: imageRect)
let roundImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return roundImage!
}
UIImage(named: "mouse")?.yy_image(byRoundCornerRadius: cornerRadius3)
以下是YYWebImage 中圆角处理的详细逻辑
- (UIImage *)yy_imageByRoundCornerRadius:(CGFloat)radius
corners:(UIRectCorner)corners
borderWidth:(CGFloat)borderWidth
borderColor:(UIColor *)borderColor
borderLineJoin:(CGLineJoin)borderLineJoin {
if (corners != UIRectCornerAllCorners) {
UIRectCorner tmp = 0;
if (corners & UIRectCornerTopLeft) tmp |= UIRectCornerBottomLeft;
if (corners & UIRectCornerTopRight) tmp |= UIRectCornerBottomRight;
if (corners & UIRectCornerBottomLeft) tmp |= UIRectCornerTopLeft;
if (corners & UIRectCornerBottomRight) tmp |= UIRectCornerTopRight;
corners = tmp;
}
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
CGContextScaleCTM(context, 1, -1);
CGContextTranslateCTM(context, 0, -rect.size.height);
CGFloat minSize = MIN(self.size.width, self.size.height);
if (borderWidth < minSize / 2) {
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, borderWidth, borderWidth) byRoundingCorners:corners cornerRadii:CGSizeMake(radius, borderWidth)];
[path closePath];
CGContextSaveGState(context);
[path addClip];
CGContextDrawImage(context, rect, self.CGImage);
CGContextRestoreGState(context);
}
if (borderColor && borderWidth < minSize / 2 && borderWidth > 0) {
CGFloat strokeInset = (floor(borderWidth * self.scale) + 0.5) / self.scale;
CGRect strokeRect = CGRectInset(rect, strokeInset, strokeInset);
CGFloat strokeRadius = radius > self.scale / 2 ? radius - self.scale / 2 : 0;
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:strokeRect byRoundingCorners:corners cornerRadii:CGSizeMake(strokeRadius, borderWidth)];
[path closePath];
path.lineWidth = borderWidth;
path.lineJoinStyle = borderLineJoin;
[borderColor setStroke];
[path stroke];
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
完整Demo可以github下载