前言
不少同學在工作中都能遇到圖文混排的需求。但是實現圖文混排的技術方案有好幾種,相應的方案優劣也有差別。今天和大家一起分享一下圖文混排的技術方案以及我的選擇。
Demo和解析工具已經開源 GitHub
現有方案
Html
結合WebView
。- 利用
CoreText
,手動解析手動佈局。 - 第三方庫,如: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
毫無疑問是一份優秀的開源元件,適合絕大部分下的業務需求。
達到圖文混排的方式有多種,這裡與大家分享的技術方案可能未必適合你們,希望能對你們在做技術選型時提供一點靈感。