服务器之家

服务器之家 > 正文

iOS设置圆角的4种方法实例(附性能评测)

时间:2021-05-19 18:26     来源/作者:溪石iOS

四种设置圆角的方法

从网上收集了各种设置圆角的方法,总结起来有以下四种:

1、设置 layer 的 cornerradius

?
1
2
view.layer.maskstobounds = yes;
view.layer.cornerradius = imgsize.width / 2;

2、用贝塞尔曲线作 mask 圆角

?
1
2
3
4
cashapelayer *layer = [cashapelayer layer];
uibezierpath *apath = [uibezierpath bezierpathwithovalinrect:view.bounds];
layer.path = apath.cgpath;
view.layer.mask = layer;

3、重新绘制圆角

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
dispatch_async(dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^{
    uiimage *image = view.image;
    image = [image drawcircleimage];
    dispatch_async(dispatch_get_main_queue(), ^{
     view.image = image;
    });
   });
////////////////////////
@implementation uiimage (roundedcorner)
 
- (uiimage *)drawcircleimage {
 cgfloat side = min(self.size.width, self.size.height);
 uigraphicsbeginimagecontextwithoptions(cgsizemake(side, side), false, [uiscreen mainscreen].scale);
 cgcontextaddpath(uigraphicsgetcurrentcontext(),
      [uibezierpath bezierpathwithovalinrect:cgrectmake(0, 0, side, side)].cgpath);
 cgcontextclip(uigraphicsgetcurrentcontext());
 cgfloat marginx = -(self.size.width - side) / 2.f;
 cgfloat marginy = -(self.size.height - side) / 2.f;
 [self drawinrect:cgrectmake(marginx, marginy, self.size.width, self.size.height)];
 cgcontextdrawpath(uigraphicsgetcurrentcontext(), kcgpathfillstroke);
 uiimage *output = uigraphicsgetimagefromcurrentimagecontext();
 uigraphicsendimagecontext();
 return output;
}
 
@end

4、混合图层,用一张镂空的透明图片作遮罩

iOS设置圆角的4种方法实例(附性能评测)
cover@2x.png

?
1
2
3
4
5
uiview *parent = [view superview];
uiimageview *cover = [[uiimageview alloc] initwithframe:cgrectmake(0, 0, imgsize.width, imgsize.height)];
cover.image = [uiimage imagenamed:@"cover"];
[parent addsubview:cover];
cover.center = view.center;

四种方法性能测试

网上流传两个结论:

  • 第一种方法会引发离屏渲染,所以是最慢的;
  • 据说第四种是效率最高的。

事实情况如何呢?

为了验证网上的结论,需要找一种性能比较的方法,这里用 instrument 的测试 fps (帧数)作为性能直观的比较值,测试过程如下:

  • 搭建collectionview 工程,连续刷新显示 1万个cell,每个cell使用相同图片,排除不同照片带来的差异;
  • 在真机下运行分别运行四种方法,用 instrument 记录,并计算平均fps;
  • 为保证平均值准确,去掉头尾帧数率过低的时间段。

iOS设置圆角的4种方法实例(附性能评测)
1. 设置 layer 的 cornerradius

iOS设置圆角的4种方法实例(附性能评测)
2. 用贝塞尔曲线作 mask 圆角

iOS设置圆角的4种方法实例(附性能评测)
3. 重新绘制圆角

iOS设置圆角的4种方法实例(附性能评测)
4. 混合图层,用一张镂空的透明图片作遮罩

结果排名如下

3 > 1 > 2 > 4

一点点优化

第四种方式不但垫底,而且出奇的慢,说明我们的实现有明显的问题,观察代码,发现原来的代码没有考虑 cell 复用,cove 视图被反复添加到cell,哪有不慢的道理!!! 于是作以下优化:

?
1
2
3
4
5
6
7
8
9
// 4. 混合图层,用一张镂空的透明图片作遮罩 (优化版)
uiview *parent = [view superview];
if (![parent viewwithtag:13]) {
 uiimageview *cover = [[uiimageview alloc] initwithframe:cgrectmake(0, 0, imgsize.width, imgsize.height)];
 cover.image = [uiimage imagenamed:@"cover"];
 cover.tag = 13;
 [parent addsubview:cover];
 cover.center = view.center;
}

这样避免了view的重复添加,fps 有了明显的回升:

iOS设置圆角的4种方法实例(附性能评测)
4.(优化版)

优化后的排名: 3 > 4 > 1 > 2

结论

测试的结论与网上流传的几乎完全不同,分析一下造成这种情况的原因:

  • 苹果在ios9后优化了 cornerradius 的绘图方式,方法1不再需要离屏渲染。
  • 方法3基于单张位图运算,方法2使用了矢量并与位图叠加,导致运算量上升,观察图2的gpu运算量高达 80.2%,证明了这一推断。

实际开发建议

  • 方法1 设置简单,性能差别不明显,简单圆角场景下推荐使用。
  • 方法4 基于透明位图,可用于异形遮罩,但需要根据图片大小做多张特殊位图,请根据实际情况选择。
  • 在位图尺寸很大,数量很多的情况下,用方法3,但要注意内存警告,最好配合缓存机制使用,避免因内存溢出而崩溃。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。

原文链接:https://www.jianshu.com/p/7699344c291f

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021德云社封箱演出完整版 2021年德云社封箱演出在线看
2021德云社封箱演出完整版 2021年德云社封箱演出在线看 2021-03-15
返回顶部