笔记-圆角四种方法的对比以及性能检测

笔记-圆角四种方法的对比以及性能检测
文章图片
这篇文章是继笔记-iOS设置圆角方法以及指定位置设圆角文章而写的,因为上篇文章发出来后,没有验证,也有同行的朋友让我给出一些测试数据来证实一下,所以这里就给出一下我个人的一些测试数据,正确是否,还请大家作为参考。--------另外,我写这个仅仅只是自己作为笔记使用,原来都是放在草稿里的,但是手机版的无法查看草稿,所以就发出来,没有想过会有人来看,所以如果有错误的内容误导了大家请原谅,也请发现错误的猿友及时帮忙提出,谢谢大家。
Core Animation工具检测离屏渲染
对离屏渲染的检测,苹果为我们提供了一个测试工具Core Animation。可以在Xcode->Open Develeper Tools->Instruments中找到。
先看看第一种方式:通过设置layer的属性
对UIImageview设置:
笔记-圆角四种方法的对比以及性能检测
文章图片
image.png 结果: 无离屏渲染
滚动的帧率:
笔记-圆角四种方法的对比以及性能检测
文章图片
image.png 结果: 接近60,趋于稳定
对UIButton设置:
笔记-圆角四种方法的对比以及性能检测
文章图片
image.png 结果: 离屏渲染
滚动的帧率:
笔记-圆角四种方法的对比以及性能检测
文章图片
image.png 如果低于40帧每秒,普通用户就会察觉明显的不流畅,现在这样app进入垃圾级别体验了。
对于文本视图实现圆角(UILabel, UIView, UITextField, UITextView
均只进行cornerRadius设置,不进行masksToBounds的设置
离屏渲染情况:
笔记-圆角四种方法的对比以及性能检测
文章图片
image.png 从上图可以看出,对于UILabel, UIView, UITextField来说,实现了圆角的设置,并没有产生离屏渲染;而对于UITextView,产生了离屏渲染。
滚动的帧率:
不存在UITextView视图的情况下
笔记-圆角四种方法的对比以及性能检测
文章图片
image.png 存在UITextView视图的情况下
笔记-圆角四种方法的对比以及性能检测
文章图片
image.png 官方对离屏渲染产生性能问题也进行了优化:
iOS9.0之前UIImageView跟UIButton设置圆角都会触发离屏渲染。
iOS9.0之后UIButton设置圆角会触发离屏渲染,而UIImageView设置圆角不会触发离屏渲染了,但是如果设置其他阴影效果之类的还是会触发离屏渲染
第二种方式:使用贝塞尔曲线UIBezierPath和Core Graphics框架画出一个圆角
对UIImageview设置:
帧率结果:
笔记-圆角四种方法的对比以及性能检测
文章图片
image.png 对UIButton设置:
帧率结果:

笔记-圆角四种方法的对比以及性能检测
文章图片
image.png
两种设置均是无离屏渲染
第三种方式:使用Core Graphics框架画出一个圆角
对UIImageview设置:
帧率结果:

笔记-圆角四种方法的对比以及性能检测
文章图片
image.png
对UIButton设置:
帧率结果:

笔记-圆角四种方法的对比以及性能检测
文章图片
image.png
两种设置均是无离屏渲染
第四种方式:使用CAShapeLayer和UIBezierPath设置圆角
对UIImageview、UIButton设置:
帧率结果:

笔记-圆角四种方法的对比以及性能检测
文章图片
8D1E59C9-800B-4C24-8F0D-27885972D683.png
【笔记-圆角四种方法的对比以及性能检测】两种都是离屏渲染,掉帧更加严重。基本上不能使用。
由上述测试可以知道,我上篇文章里所记笔记是有问题的。这里的测试结果可以看的彻底。
新方法:实际可采取利用 混合图层
在需要裁剪的视图上面添加一层视图,以达到圆角的效果。效果如下:
笔记-圆角四种方法的对比以及性能检测
文章图片
image.png 布局图如下:

笔记-圆角四种方法的对比以及性能检测
文章图片
image.png 对于UIImageViewUIButton均可使用,且无离屏渲染
滚动的帧率:

笔记-圆角四种方法的对比以及性能检测
文章图片
image.png 代码如下:

- (void)drawRoundedCornerImage { UIImageView *iconImgV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)]; iconImgV.image = [UIImage imageNamed:@"icon"]; [self.view addSubview:iconImgV]; [iconImgV mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(iconImgV.size); make.top.equalTo(self.view.mas_top).offset(500); make.centerX.equalTo(self.view); }]; UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)]; [self.view addSubview:imgView]; [imgView mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(imgView.size); make.top.equalTo(iconImgV.mas_top); make.leading.equalTo(iconImgV.mas_leading); }]; // 圆形 imgView.image = [self drawCircleRadius:100 outerSize:CGSizeMake(200, 200) fillColor:[UIColor whiteColor]]; }// 绘制圆形 - (UIImage *)drawCircleRadius:(float)radius outerSize:(CGSize)outerSize fillColor:(UIColor *)fillColor { UIGraphicsBeginImageContextWithOptions(outerSize, false, [UIScreen mainScreen].scale); // 1、获取当前上下文 CGContextRef contextRef = UIGraphicsGetCurrentContext(); //2.描述路径 // ArcCenter:中心点 radius:半径 startAngle起始角度 endAngle结束角度 clockwise:是否逆时针 UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(outerSize.width * 0.5, outerSize.height * 0.5) radius:radius startAngle:0 endAngle:M_PI * 2 clockwise:NO]; [bezierPath closePath]; // 3.外边 [bezierPath moveToPoint:CGPointMake(0, 0)]; [bezierPath addLineToPoint:CGPointMake(outerSize.width, 0)]; [bezierPath addLineToPoint:CGPointMake(outerSize.width, outerSize.height)]; [bezierPath addLineToPoint:CGPointMake(0, outerSize.height)]; [bezierPath addLineToPoint:CGPointMake(0, 0)]; [bezierPath closePath]; //4.设置颜色 [fillColor setFill]; [bezierPath fill]; CGContextDrawPath(contextRef, kCGPathStroke); UIImage *antiRoundedCornerImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return antiRoundedCornerImage; }

此方法就是在要添加的视图上在叠加一个部分透明的视图,只对圆角部分进行遮挡。图层混合的透明度处理方式与mask正好相反。
此方法没有离屏渲染,也可以自定义设置指定任意角为圆角。
总结
  • 在可以使用混合图层遮挡的场景下,优先使用。
  • 通过.layer属性设置,综合性能上,还是有很大优势的。

    推荐阅读