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

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

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

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

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

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

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

  以下为笔者方案与标哥开源库的比较

  一、 突破口的选择

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

  二、 功能及解决问题

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

  三、 外观呈现

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

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

  

  四、CPU和内存  

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

标哥方案
笔者方案

  

  五、 帧速

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

标哥方案
笔者方案

    六、代码量

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

    七、侵入性和易用性

 以下为笔者两个辅助类的头文件声明和暴露的使用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

     八、适用场景

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

     九、总结

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

 

时间: 2024-08-24 15:28:07

iOS中如何优雅的添加圆角和边框?的相关文章

关于iOS中UIView类视图的圆角

iOS开发中,常常由于需求,而需要圆角的样式.如果4个角都是圆角的,还好说.一行两行代码就可以搞定.就是CAlayer.可是现在我想说下不规则的圆角.目前我还没有找到更好的方法来画圆角.希望有解决方法的朋友看到这篇文章,能交流学习下. 1 UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:sourceView.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRe

ios中tableview的移动添加删除

// // MJViewController.m // UITableView-编辑模式 // // Created by mj on 13-4-11. // Copyright (c) 2013年 itcast. All rights reserved. // #import "MJViewController.h" @interface MJViewController () { // 当前的编辑模式 UITableViewCellEditingStyle _editingStyl

iOS中为网站添加图标到主屏幕以及增加启动画面

虽然没有能力开发Native App,但还是可以利用iOS中Safari浏览器的特性小小的折腾一下,做一个伪Web App满足下小小的虚荣心的. 既然是在iOS中的Safari折腾的,那么代码中利用到的也基本上都是Safari的私有属性. 添加图标到主屏幕是Web App的第一步: <link rel="apple-touch-icon-precomposed" sizes="57x57" href="icon-57.png"> &l

iOS 中 为cagetory 添加属性

我们知道 在iOS中cagetory里面只能添加方法 ,如果我们想添加属性 就要用到 <objc/runtime.h> 中 OBJC_EXPORT void objc_setAssociatedObject(idobject, constvoid *key, id value, objc_AssociationPolicy policy)__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);OBJC_EXPORT id objc_getAssoc

iOS 高效添加圆角效果实战讲解

圆角(RounderCorner)是一种很常见的视图效果,相比于直角,它更加柔和优美,易于接受.但很多人并不清楚如何设置圆角的正确方式和原理.设置圆角会带来一定的性能损耗,如何提高性能是另一个需要重点讨论的话题.我查阅了一些现有的资料,收获良多的同时也发现了一些误导人错误.本文总结整理了一些知识点,概括如下: 设置圆角的正确姿势及其原理 设置圆角的性能损耗 其他设置圆角的方法,以及最优选择 我为本文制作了一个 demo,读者可以在我的 github 上 clone 下来:CornerRadius

iOS中创建自定义的圆角按钮

iOS中很多时候都需要用到指定风格的圆角按钮,尽管UIButton提供了一个方式创建圆角按钮: + (id)buttonWithType:(UIButtonType)buttonType;//指定buttonType为UIButtonTypeRoundedRect 但是这样创建出来的按钮仅仅能支持默认的白底蓝字的风格,不可再进行更改.比如更改了backgroundColor,背景颜色区域仍然覆盖了整个矩形区域. 怎么做呢,通过摸索,以下方法能达到要求: UIButton *btn = [[UIB

UILabel iOS中添加文字的控件

UILabel是iOS中的控件,是UIView的子类,只是在UIView的基础上添加了文字显示功能.UILabel也是视图使用过程和UIView类似 //1.创建视图对象 //2.配置视图属性 //3.添加到父视图 //4.释放所有权 //1.创建对象 UILabel *aLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, 280, 40)]; //2.配置属性 //(1.)背景颜色 aLabel.backgroundColor

在iOS开发中,给项目添加新的.framework

首先需要了解一下iOS中静态库和动态库.framework的概念 静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人看到源码,就需要以库的形式进行封装,只暴露出头文件.另外一种情况是,对于某些不会进行大的改动的代码,我们想减少编译的时间,就可以把它打包成库,因为库是已经编译好的二进制了,编译的时候只需要 Link 一下,不会浪费编译时间. 上面提到

[转载]iOS中侧边栏的添加

原文地址:iOS中侧边栏的添加作者:伤心的小果冻 1.添加系统框架 2.添加三方类库 3.创建一个MenuViewController作为侧边滑动时候显示的视图 //  MenuViewController.h //  sideTableView // //  Created by Dong on 13-9-26. //  Copyright (c) 2013年 dong. All rights reserved. // #import <UIKit/UIKit.h> @interface M