ZJAttributedText是高性能轻量级富文本框架前言
如果遇到上面一个需求,你会怎么处理,若干个UILabel+UIImageView?NSAttributedStrig拼接?CoreText?
我相信不论是哪种方式代码量都不小,并且难以复用,其他语言写富文本是那么轻松,Adroid天生支持简单HTML,RN(JS)标签套标签,而只要用过iOS中的富文本都会觉得难用...目前业界功能强大、较为好用的是YYText,但设计思想是尽可能与UILabel、UITextView相似,所以相对使用也不是特别简单,而且框架较重。
基于现状开发了一套轻量的框架 ZJAttributedText,ZJAttributedText是高性能轻量级富文本框架,满足大部分富文本需求,并且提供了手势响应、绘制回调、图文对齐、CoreText属性扩展、支持网络图片、异步绘制性能优化,最重要的是使用简单,通过链式语法轻松写出一篇图文混排文本.
示例说明如图所示一篇图文混排,涉及到字体,颜色,字间距,行间距,图片对齐,文字对齐,描边等等属性,还有网络图片与本地图片混排,手势响应等需求,使用本框架可以下面这样实现:
//...省略常量声明 //标题 title.fot(titleFot).color(titleColor).oClicked(titleOClicked).oLayout(titleOLayout); //首段 firstPara.color(firstParaColor).alig(@0); //图片需要用一个空字符串起头 NSStrig *webImageStrig = @"".apped(webImageURL).fot(separateLieFot).miLieHeight(@100); //分割线 separateLie.fot(separateLieFot).strokeColor(separateLieColor).strokeWidth(@1); //本地图片 NSStrig *locolImageStrig = @"".apped(locolImage); //最后一段 lastPara.fot(lastParaFot).alig(@1); //书名 bookName.fot(bookNameFot).color(bookNameColor).oClicked(bookOClicked).alig(@1); //引用 quote.color(quoteColor).letterSpace(@0).miLieSpace(@8).alig(@0); //设置全局默认属性, 优先级低于指定属性 NSStrig *defaultAttributes = @"".etire() .maxSize(maxSize).alig(@2).letterSpace(@3).miLieHeight(@20).maxLieHeight(@20).imageAlig(@1).oClicked(textOClicked).imageSize(imageSize); //拼接 title.apped(firstPara).apped(webImageStrig).apped(separateLie).apped(locolImageStrig).apped(lastPara).apped(bookName).apped(quote) //设置默认属性 .apped(defaultAttributes) //绘制View .drawView(^(UIView *drawView) { [self.view addSubview:drawView]; });甚至可以这样实现:
//...省略常量声明 @"" //拼接全文 .apped(title).fot(titleFot).color(titleColor).oClicked(titleOClicked).oLayout(titleOLayout) .apped(firstPara).color(firstParaColor).alig(@0) .apped(webImageURL).fot(separateLieFot).miLieHeight(@100) .apped(separateLie).fot(separateLieFot).strokeColor(separateLieColor).strokeWidth(@1) .apped(locolImage) .apped(lastPara).fot(lastParaFot).alig(@1) .apped(bookName).fot(bookNameFot).color(bookNameColor).oClicked(bookOClicked).alig(@1) .apped(quote).color(quoteColor).letterSpace(@0).miLieSpace(@8).alig(@0) //设置默认属性 .etire().maxSize(maxSize).alig(@2).letterSpace(@3).miLieHeight(@20).maxLieHeight(@20).imageAlig(@1).oClicked(textOClicked).imageSize(imageSize) //绘制 .drawView(^(UIView *drawView) { [self.view addSubview:drawView]; });核心方法与属性对NSStrig的扩展
核心方法
apped(idcotet)
拼接cotet 可以是文本(NSStrig)、图片(UIImage)、图片链接(NSURL)(必须指定imageSize属性)、视图(CALayer/UIView)etire()
设置整段富文本优先级低于指定属性, 较为重要的属性 maxSize 设置绘制约束, 部分段落属性只在整段中设置生效drawLayer(^(CALayer*drawLayer)completio)
绘制layer, 无法响应手势drawView(^(UIView*drawView)completio)
绘制View, 可响应手势属性
通用属性
verticalOffset垂直偏移
oClicked点击回调
oLayout展示回调
cacheFrame缓存该段文本绘制位置
字符串属性
fot字体:文字字体/图片居中对齐字体
color颜色
letterSpace字间距
strokeWidth描边宽度,整数为镂空,Color不生效;负数Color生效
strokeColor描边颜色
verticalForm文字绘制随文字书写方向,默认否(0),是(非0)
uderlie下划线类型,整形,0为oe,1为细线2为加粗9为双条参考CTUderlieStyle(仅枚举了三种,其他值也有不同效果)
图片属性
imageSize图片尺寸,默认为图片本身尺寸,会根据图片缩放(2x3x)自动调整
imageAlig图片对齐模式,0为默认,基准线对齐.1为居中对齐至特定字体大小参看ZJTextImageAlig
段落属性
maxSize绘制的约束尺寸,默认不限制
miLieSpace最小行间距
maxLieSpace最大行间距
miLieHeight最小行高
maxLieHeight最小行高
alig对齐,整形,0为默认靠左1为靠右2为居中,参考CTTextAligmet
lieBreakMode对齐,整形,参考NSLieBreakMode
性能总体采用CoreText+异步绘制图片完成,理论上性能会比较高,经过测试如下数据供参考:
内容:一段文本加上两张图片
机型:iPhoe6
测试结果:
常规(使用NSAttributedStrig+UILabel)过程:创建->显示(绘制)常规分析:
主线程代码在28ms左右.(主线程代码开始至结束耗时)
UILabel显示(绘制)耗时在42ms左右.(addSubview至drawRect耗时)
综合耗时70ms左右,全部在主线程
异步绘制(本框架)过程:创建->异步绘制->显示异步绘制分析:
主线程(创建)代码在28ms左右.(主线程代码开始至结束耗时)
创建(主线程)+异步绘制耗时84ms左右.(主线程代码开始至绘制出图片回调)
由1、2得出子线程绘制耗时56ms左右,另外经过多次试验(大段文字绘制)得出绘制复杂的段落也耗时增长较少
显示耗时0.75ms左右.(addSubview至drawRect耗时)
综合耗时85ms左右,其中主线程29ms,子线程56ms
结论:
相较于常规方式降低了主线程压力70ms->29ms
越复杂的文本收益越高(多控件合一,异步绘制),上图中大段富文本绘制时间也只多了15ms,耗时增长少
总体耗时增加了15ms,都在子线程,毕竟处理的逻辑比系统的多.
安装GithubZJAttributedText
Podpod 'ZJAttributedText'本框架依赖SDWebImage(几乎所有App都集成了,可以共用一套缓存逻辑)
尾巴内部实现代码不多,几乎所有步骤都添加了注释,如果需要学习CoreText,异步绘制,链式语法,还算是个不错的Demo,如果大家感兴趣,可以补充下CoreText相关内容,这部分网上的资料都比较老,错误也比较多.欢迎issue与star~













评论