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

这篇文章是继笔记-iOS设置圆角方法以及指定位置设圆角文章而写的,由于上篇文章发出来后,没有验证,也有同行的朋友让我给出一些测试数据来证明一下,因此这里就给出一下我我的的一些测试数据,正确是否,还请你们做为参考。--------另外,我写这个仅仅只是本身做为笔记使用,原来都是放在草稿里的,可是手机版的没法查看草稿,因此就发出来,没有想过会有人来看,因此若是有错误的内容误导了你们请原谅,也请发现错误的猿友及时帮忙提出,谢谢你们。bash

Core Animation工具检测离屏渲染

对离屏渲染的检测,苹果为咱们提供了一个测试工具Core Animation。能够在Xcode->Open Develeper Tools->Instruments中找到。markdown

先看看第一种方式:经过设置layer的属性

对UIImageview设置:app

结果: 无离屏渲染框架

滚动的帧率:工具

结果: 接近60,趋于稳定

对UIButton设置:布局

结果: 离屏渲染

滚动的帧率:post

若是低于40帧每秒,普通用户就会察觉明显的不流畅,如今这样app进入垃圾级别体验了。性能

对于文本视图实现圆角(UILabel, UIView, UITextField, UITextView测试

均只进行cornerRadius设置,不进行masksToBounds的设置优化

离屏渲染状况:

从上图能够看出,对于UILabel, UIView, UITextField来讲,实现了圆角的设置,并无产生离屏渲染;而对于UITextView,产生了离屏渲染。

滚动的帧率:
不存在UITextView视图的状况下

存在UITextView视图的状况下

官方对离屏渲染产生性能问题也进行了优化:

iOS9.0以前UIImageView跟UIButton设置圆角都会触发离屏渲染。

iOS9.0以后UIButton设置圆角会触发离屏渲染,而UIImageView设置圆角不会触发离屏渲染了,可是若是设置其余阴影效果之类的仍是会触发离屏渲染

第二种方式:使用贝塞尔曲线UIBezierPath和Core Graphics框架画出一个圆角

对UIImageview设置:
帧率结果:

对UIButton设置:
帧率结果:

两种设置均是无离屏渲染

第三种方式:使用Core Graphics框架画出一个圆角

对UIImageview设置:
帧率结果:

对UIButton设置:
帧率结果:

两种设置均是无离屏渲染

第四种方式:使用CAShapeLayer和UIBezierPath设置圆角

对UIImageview、UIButton设置:
帧率结果:

两种都是离屏渲染,掉帧更加严重。基本上不能使用。

由上述测试能够知道,我上篇文章里所记笔记是有问题的。这里的测试结果能够看的完全。

新方法:实际可采起利用

混合图层

在须要裁剪的视图上面添加一层视图,以达到圆角的效果。效果以下:

布局图以下:

对于UIImageViewUIButton都可使用,且无离屏渲染

滚动的帧率:

代码以下:

- (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);
    
    // 一、获取当前上下文
    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属性设置,综合性能上,仍是有很大优点的。
相关文章
相关标签/搜索