iOS中如何优雅的添加圆角和边框?

  由于项目须要,整理了下圆角和边框辅助类。想起前几天标哥还在微博里问圆角在tableView里卡顿的问题,想着去炫耀下。去到标哥的博客,发现已经有必定程度解决给出开源库而且在推广,迭代了好几个版本了。。git

  圆角这东西被无数性能追求者津津乐道,无数小白们高山仰止。 至于圆角的几种实现方案,设置cornerRadius、加maskLayer、直接加镂空图、内存异步裁剪等等,网络上一搜一大把,这里就再也不重复了。这里有两点要提醒下,纹理裁剪才是off-screen rendering的缘由,而不是设置圆角。固然你要是做死的去设了layer的fillColor,再来设圆角,那就只能说no zuo no die ;另外在使用光栅化时,必定要设置scale以适配屏幕分辨率。github

  既然标哥都给出开源方案了,那就比较一下,检查下本身的不足吧。为参照相同的运行条件,笔者把本身写的辅助类放到标哥的Demo里,实现相同的效果。而后设计思路、外观呈现、CPU和内存、帧速、代码量、侵入性和易用性、适用场景等个方面作出比较。缓存

  标哥的开源库:https://github.com/CoderJackyHuang/HYBImageCliped网络

  笔者fork后修改的项目:https://github.com/1962449521/HYBImageCliped异步

  该功能类的在线维护:https://github.com/1962449521/WHUCornerMaker性能

  笔者整理中的辅助类集:https://github.com/1962449521/WHUKit/tree/master/WHUKitDemo/WHUKitDemo/WHUKit优化

 

  如下为笔者方案标哥开源库的比较编码

  1、 突破口的选择spa

  标哥选择的起点是内存中剪裁图片,经过缓存策略优化性能,给UIView、UIImageView、UIButton等控件增长Category以扩展功能。笔者选择的起点是绘制镂空图,一样使用了缓存以提升复用。由于长期开发SDK尽可能不使用Category的习惯,笔者采用辅助类的形式提供功能实现设计

  2、 功能及解决问题

  主要的出发点都是为了解决圆角图片离屏渲染影响滑动帧速的问题。标哥采用了剪裁图片的方式,可以适应背景非单色状况;在控件内部的图片,能提供圆角效果,好比按钮内非抵边的image;在边线的绘制上,提供了形状边框,边框有填充和边线。笔者提供的辅助类只适用背景单色,裁剪针对UIView或其子类总体,边线只提供单线。

  3、 外观呈现

   除了双色边线外,其它的外观都能作到相同的效果。

标哥静态容器 笔者静态容器
标哥collectionView 笔者collectionView

  

  4、CPU和内存  

  标哥方案CPU使用骤增,最高达到82%。内存使用也高于笔者。由于笔者采用了每次cell出现时重绘边角,因此CPU略高。若是肯定每次cell重用时边角位置正确,能够不重绘边角,CPU能稳定在13%左右。图片相对较少,内存使用差异不明显。当不一样图片较多时,标哥使用方案需大量缓存裁切好的图片,猜想会在内存使用上随之增长。而笔者方案会复用相同角度颜色的边角,图片增多时不会增长圆角图片的内存开销。

标哥方案
笔者方案

  

  5、 帧速

  滑动帧速基本相近,都有较好的体验,笔者方案数值相对较高。

标哥方案
笔者方案

    6、代码量

  标哥使用了一个管理类HYBImageClipedManager,以及提供了UIImage、UIView、UIButton三个类的category,总共约1千行代码。笔者提供了WHUCornerMaker、WHUBorderMaker两个辅助功能类,约250行代码。

    7、侵入性和易用性

  如下为笔者两个辅助类的头文件声明和暴露的使用API,自认为仍是较为清晰易用的。这里要说到关于注释,多余的注释是违反DRY原则的,不过因为国人对英文的理解不直接或者项目编码约定,而加了许多没必要要的注释。仍是应当以清晰符合语义的方法、变量命名做为首选。至于标哥提供的接入设计,方法太多就不在这里列出了,感兴趣的童鞋能够从本文提供的连接跳入查看^^

@interface WHUCornerMaker : NSObject

+ (BOOL) isCorneredAtView:(UIView * _Nonnull)view;

// 优先选取view 沿superview上的父类容器的背景色, 若是一直为nil, 则取defaultColor 做为圆角颜色

- (void) roundView:( UIView * _Nonnull ) view withCornerRadius:(CGFloat) radius defaultColor:( UIColor * _Nullable)color;

- (void) roundViews:(NSArray<UIView *> * _Nonnull) views withCornerRadius:(CGFloat) radius  defaultColor:( UIColor * _Nullable)color;

- (void) roundView:(UIView * _Nonnull) view withCornerRadius:(CGFloat) radius defaultColor:( UIColor * _Nullable)color byRoundingCorners:(UIRectCorner)corners;

- (void) roundViews:(NSArray<UIView *> * _Nonnull) views withCornerRadius:(CGFloat) radius  defaultColor:( UIColor * _Nullable)color  byRoundingCorners:(UIRectCorner)corners;


@end
@interface WHUBorderMaker : NSObject

+ (void) borderView:( UIView * _Nonnull ) view withCornerRadius:(CGFloat) radius width:(CGFloat)borderWidth color:(UIColor * _Nonnull)borderColor;


+ (void) borderView:( UIView * _Nonnull ) view withCornerRadius:(CGFloat) radius width:(CGFloat)borderWidth color:(UIColor * _Nonnull)borderColor byRoundingCorners:(UIRectCorner)corners;

@end

 

     8、适用场景

  不能否认,标哥提供了更多功能,好比拿到裁切的图片,绘制双色边框等。不过这样的使用场景应该是较少的,笔者提供了辅助类能知足大多数场景的需求。

 

     9、总结

在作通用性开源库的时候,可能会考虑更多的东西。但花80%的精力去实现5%使用者的需求是否有必要是有待斟酌的。在笔者方案和标哥方案的比较中,整体而言笔者的方案性能是高出不少,并不随使用条件复杂性的增长而性能下降。这一方面是内存裁剪图片本就是骑虎难下的选择,一方面也是笔者只针对有限的使用场景和需求。