iOS - 图文混排技术方案分享

4,443 阅读4分钟

前言

不少同学在工作中都能遇到图文混排的需求。但是实现图文混排的技术方案有好几种,相应的方案优劣也有差别。今天和大家一起分享一下图文混排的技术方案以及我的选择。

Demo和解析工具已经开源 GitHub

现有方案

  1. Html结合WebView
  2. 利用CoreText,手动解析手动布局。
  3. 第三方库,如:YYText

先说第一种方案,优点是:对于客户端来说,开发难度和代码量都是比较小的。同时也能做到随心所欲的布局,不需要考虑图片,缓存,和交互等等问题。缺点是:需要准备相应的Html页面,如果页面中涉及到权限验证,处理起来比较麻烦,另外,如果在业务场景复杂的情况下,针对性能和交互的优化需要花更多的时间。

第二种方案,通过原生的CoreText,使我们能接管整个图文排版过程中数据的管理以及界面的排布展示,优点是:自由度高,能够随心所欲展示排版样式、交互方式,效率上比较高。缺点是:代码量比较大,需要自己造好几个轮子,并且因为需要关注的地方比较多,如:图片缓存,排版交互等,开发周期上会比较长,同时前后端数据交互格式也需要相互配合。

第三种方案,这个方案省去造轮子的时间,可以将注意力放在排版和优化上,笔者采用的也是这个方案。

主要流程

获取数据

在获取数据的环节,重点在于前后端对于数据格式的配合。这一步直接影响了接下来我们解析数据的工作。 根据业务需求,分别有多少种布局,需要设计好具体的数据规则,按照预定好的设计规则将数据传递给移动端。在这个环节,团队经过讨论的结果是直接沿用Html的数据规则。这么做的优点是,这是一套成熟的规则,不需要我们另外去针对复杂的布局设定复杂的规则,日后便于维护,对于后端来说也更为友好,不需要花费太多的时间对数据重新处理。

"<p>9.微分方程<img width="67" height="21" src="http://xxx.xxx/xxxxxxx.gif" align="absmiddle" />的特征方程为______.</p>"

解析数据 & 数据缓存

在解析数据的环节,需要做的就是将得到的数据,按照事先约定好的规则进行解析。当然,数据内容的缓存也可以在解析之前做。在解析数据之前做数据缓存的好处是可以通过多线程来将解析数据和数据缓存两个工作并行进行,效率较高,缺点就是日后数据再取出来复用的时候需要再跑一次解析过程。

我的解析的大致思路是:通过正则先找出文本中的图片,经过处理,如:图片缩放,拼接地址等,再使用NSMutableAttributedString的构造方法,生成NSMutableAttributedString,到这一步数据解析已经基本完成。

+ (NSMutableAttributedString *)outputAttributedString:(NSString *)html{
    NSData *data = [html dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableAttributedString * mutAttributedStr = [[NSMutableAttributedString alloc] initWithAttributedString:[[NSAttributedString alloc] initWithData:data options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)} documentAttributes:NULL error:nil]];
    return mutAttributedStr;
}

YYText

到了这一步,主要是利用YYText提供的接口和类来做布局。 我的做法是构造一个继承于YYTextAttachment,将上一步处理好的数据中找到图片部分替换成YYTextAttachment,将图片的展示交给YYTextAttachment,并且YYTextAttachment能够接受UIImageView类型的Content,这样一来可以直接使用SDWebImage来做图片缓存。并且可以在UIImageView中方便的添加点击事件。 另外,通过YYTextLayout可以灵活地实现我们预想的布局。

总结

webView的方式适合轻量级以及简单的业务需求的页面,并且具备灵活性。

CoreText的方式适合较为发杂的业务场景以及较长的开发时间。

YYText毫无疑问是一份优秀的开源组件,适合绝大部分下的业务需求。

达到图文混排的方式有多种,这里与大家分享的技术方案可能未必适合你们,希望能对你们在做技术选型时提供一点灵感。