UIImageView圆角,教你远离cornerRadius

日常我们使用layer的两个属性,简单的两行代码就能实现圆角的呈现

imageView.layer.masksToBounds = YES;
imageView.layer.cornerRadius = 10.f; 

由于设置masksToBounds 会导致离屏渲染(离屏渲染:GPU在当前屏幕缓冲区外新开辟一个渲染缓冲区进行工作),这会给我们带来额外的性能损耗,如果这样的圆角操作达到一定数量,会触发缓冲区的频繁合并和上下文的的频繁切换,性能的代价会宏观地表现在用户体验上----掉帧。
当然这些效果不会直接显示在屏幕上,可以使用Instruments的CoreAnimation检测,当然你也可以自己写一个检测帧频的方法。

那如何高效的为UIImageView创建圆角?

修改image为圆角图片

图片进行了切角处理后,将得到的含圆角UIImage通过setImage传给了UIImageView。操作没有触发GPU离屏渲染,过程在CPU内完成。

/** * @brief clip the cornerRadius with image, UIImageView must be setFrame before, no off-screen-rendered */
- (void)zy_cornerRadiusWithImage:(UIImage *)image cornerRadius:(CGFloat)cornerRadius rectCornerType:(UIRectCorner)rectCornerType { 
    CGSize size = self.bounds.size; 
    CGFloat scale = [UIScreen mainScreen].scale; 
    CGSize cornerRadii = CGSizeMake(cornerRadius, cornerRadius);     
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
        UIGraphicsBeginImageContextWithOptions(size, YES, scale); 
        if (nil == UIGraphicsGetCurrentContext()) { 
            return; 
        } 
        UIBezierPath *cornerPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:rectCornerType cornerRadii:cornerRadii]; 
        [cornerPath addClip]; 
        [image drawInRect:self.bounds]; 
        id processedImageRef = (__bridge id _Nullable)(UIGraphicsGetImageFromCurrentImageContext().CGImage); 
        UIGraphicsEndImageContext(); 
        dispatch_async(dispatch_get_main_queue(), ^{ 
            self.layer.contents = processedImageRef; 
        }); 
    });
}

圆角路径直接用贝塞尔曲线绘制,并且还有个意想不到的效果是可以选择哪几个角有圆角效果。

延伸:如何高效的为UIView创建圆角?

做法的原理是手动画出圆角的image,在UIView上增加一层UIImageView,将image赋值给UIImageView。
当然,简单的做法是设计的美工自己做一张带有圆角效果的图片,根据大小拉伸。这样的一个好处是以防美工随意更改圆角的角度

你可能感兴趣的:(UIImageView圆角,教你远离cornerRadius)