ZJAttributedText iOS 轻量级富文本框架开源项目

我要开发同款
匿名用户2018年06月29日
111阅读
开发技术Object-c
所属分类Objective-C、iOS/iPhone/iPad开发包、手机/移动开发
授权协议MIT

作品详情

ZJAttributedText是高性能轻量级富文本框架前言

如果遇到上面一个需求,你会怎么处理,若干个UILabel+UIImageView?NSAttributedString拼接?CoreText?

我相信不论是哪种方式代码量都不小,并且难以复用,其他语言写富文本是那么轻松,Android天生支持简单HTML,RN(JS)标签套标签,而只要用过iOS中的富文本都会觉得难用...目前业界功能强大、较为好用的是YYText,但设计思想是尽可能与UILabel、UITextView相似,所以相对使用也不是特别简单,而且框架较重。

基于现状开发了一套轻量的框架 ZJAttributedText,ZJAttributedText是高性能轻量级富文本框架,满足大部分富文本需求,并且提供了手势响应、绘制回调、图文对齐、CoreText属性扩展、支持网络图片、异步绘制性能优化,最重要的是使用简单,通过链式语法轻松写出一篇图文混排文本.

示例说明

如图所示一篇图文混排,涉及到字体,颜色,字间距,行间距,图片对齐,文字对齐,描边等等属性,还有网络图片与本地图片混排,手势响应等需求,使用本框架可以下面这样实现:

    //...省略常量声明    //标题    title.font(titleFont).color(titleColor).onClicked(titleOnClicked).onLayout(titleOnLayout);    //首段    firstPara.color(firstParaColor).align(@0);    //图片需要用一个空字符串起头    NSString *webImageString = @"".append(webImageURL).font(separateLineFont).minLineHeight(@100);    //分割线    separateLine.font(separateLineFont).strokeColor(separateLineColor).strokeWidth(@1);    //本地图片    NSString *locolImageString = @"".append(locolImage);    //最后一段    lastPara.font(lastParaFont).align(@1);    //书名    bookName.font(bookNameFont).color(bookNameColor).onClicked(bookOnClicked).align(@1);    //引用    quote.color(quoteColor).letterSpace(@0).minLineSpace(@8).align(@0);        //设置全局默认属性, 优先级低于指定属性    NSString *defaultAttributes = @"".entire()    .maxSize(maxSize).align(@2).letterSpace(@3).minLineHeight(@20).maxLineHeight(@20).imageAlign(@1).onClicked(textOnClicked).imageSize(imageSize);        //拼接    title.append(firstPara).append(webImageString).append(separateLine).append(locolImageString).append(lastPara).append(bookName).append(quote)    //设置默认属性    .append(defaultAttributes)    //绘制View    .drawView(^(UIView *drawView) {        [self.view addSubview:drawView];    });

甚至可以这样实现:

    //...省略常量声明    @""    //拼接全文    .append(title).font(titleFont).color(titleColor).onClicked(titleOnClicked).onLayout(titleOnLayout)    .append(firstPara).color(firstParaColor).align(@0)    .append(webImageURL).font(separateLineFont).minLineHeight(@100)    .append(separateLine).font(separateLineFont).strokeColor(separateLineColor).strokeWidth(@1)    .append(locolImage)    .append(lastPara).font(lastParaFont).align(@1)    .append(bookName).font(bookNameFont).color(bookNameColor).onClicked(bookOnClicked).align(@1)    .append(quote).color(quoteColor).letterSpace(@0).minLineSpace(@8).align(@0)    //设置默认属性    .entire().maxSize(maxSize).align(@2).letterSpace(@3).minLineHeight(@20).maxLineHeight(@20).imageAlign(@1).onClicked(textOnClicked).imageSize(imageSize)    //绘制    .drawView(^(UIView *drawView) {        [self.view addSubview:drawView];    });核心方法与属性

对NSString的扩展

核心方法

append(idcontent)

拼接content 可以是文本(NSString)、图片(UIImage)、图片链接(NSURL)(必须指定imageSize属性)、视图(CALayer/UIView)

entire()

设置整段富文本优先级低于指定属性, 较为重要的属性 maxSize 设置绘制约束, 部分段落属性只在整段中设置生效

drawLayer(^(CALayer*drawLayer)completion)

绘制layer, 无法响应手势

drawView(^(UIView*drawView)completion)

绘制View, 可响应手势

属性

通用属性

verticalOffset垂直偏移

onClicked点击回调

onLayout展示回调

cacheFrame缓存该段文本绘制位置

字符串属性

font字体:文字字体/图片居中对齐字体

color颜色

letterSpace字间距

strokeWidth描边宽度,整数为镂空,Color不生效;负数Color生效

strokeColor描边颜色

verticalForm文字绘制随文字书写方向,默认否(0),是(非0)

underline下划线类型,整形,0为none,1为细线2为加粗9为双条参考CTUnderlineStyle(仅枚举了三种,其他值也有不同效果)

图片属性

imageSize图片尺寸,默认为图片本身尺寸,会根据图片缩放(2x3x)自动调整

imageAlign图片对齐模式,0为默认,基准线对齐.1为居中对齐至特定字体大小参看ZJTextImageAlign

段落属性

maxSize绘制的约束尺寸,默认不限制

minLineSpace最小行间距

maxLineSpace最大行间距

minLineHeight最小行高

maxLineHeight最小行高

align对齐,整形,0为默认靠左1为靠右2为居中,参考CTTextAlignment

lineBreakMode对齐,整形,参考NSLineBreakMode

性能

总体采用CoreText+异步绘制图片完成,理论上性能会比较高,经过测试如下数据供参考:

内容:一段文本加上两张图片

机型:iPhone6

测试结果:

常规(使用NSAttributedString+UILabel)过程:创建->显示(绘制)常规分析:

主线程代码在28ms左右.(主线程代码开始至结束耗时)

UILabel显示(绘制)耗时在42ms左右.(addSubview至drawRect耗时)

综合耗时70ms左右,全部在主线程

异步绘制(本框架)过程:创建->异步绘制->显示异步绘制分析:

主线程(创建)代码在28ms左右.(主线程代码开始至结束耗时)

创建(主线程)+异步绘制耗时84ms左右.(主线程代码开始至绘制出图片回调)

由1、2得出子线程绘制耗时56ms左右,另外经过多次试验(大段文字绘制)得出绘制复杂的段落也耗时增长较少

显示耗时0.75ms左右.(addSubview至drawRect耗时)

综合耗时85ms左右,其中主线程29ms,子线程56ms

结论:

相较于常规方式降低了主线程压力70ms->29ms

越复杂的文本收益越高(多控件合一,异步绘制),上图中大段富文本绘制时间也只多了15ms,耗时增长少

总体耗时增加了15ms,都在子线程,毕竟处理的逻辑比系统的多.

安装Github

ZJAttributedText

Podpod 'ZJAttributedText'

本框架依赖SDWebImage(几乎所有App都集成了,可以共用一套缓存逻辑)

尾巴

内部实现代码不多,几乎所有步骤都添加了注释,如果需要学习CoreText,异步绘制,链式语法,还算是个不错的Demo,如果大家感兴趣,可以补充下CoreText相关内容,这部分网上的资料都比较老,错误也比较多.欢迎issue与star~

声明:本文仅代表作者观点,不代表本站立场。如果侵犯到您的合法权益,请联系我们删除侵权资源!如果遇到资源链接失效,请您通过评论或工单的方式通知管理员。未经允许,不得转载,本站所有资源文章禁止商业使用运营!
下载安装【程序员客栈】APP
实时对接需求、及时收发消息、丰富的开放项目需求、随时随地查看项目状态

评论