資料介紹
軟件簡(jiǎn)介
ZJAttributedText 是高性能輕量級(jí)富文本框架
前言
如果遇到上面一個(gè)需求, 你會(huì)怎么處理, 若干個(gè) UILabel + UIImageView? NSAttributedString拼接? CoreText?
我相信不論是哪種方式代碼量都不小, 并且難以復(fù)用, 其他語(yǔ)言寫富文本是那么輕松, Android 天生支持簡(jiǎn)單 HTML, RN(JS) 標(biāo)簽套標(biāo)簽, 而只要用過(guò) iOS 中的富文本都會(huì)覺(jué)得難用... 目前業(yè)界功能強(qiáng)大、較為好用的是 YYText, 但設(shè)計(jì)思想是盡可能與 UILabel、UITextView 相似, 所以相對(duì)使用也不是特別簡(jiǎn)單, 而且框架較重。
基于現(xiàn)狀開(kāi)發(fā)了一套輕量的框架?ZJAttributedText,ZJAttributedText 是高性能輕量級(jí)富文本框架,滿足大部分富文本需求, 并且提供了手勢(shì)響應(yīng)、 繪制回調(diào)、 圖文對(duì)齊、 CoreText 屬性擴(kuò)展、 支持網(wǎng)絡(luò)圖片、 異步繪制性能優(yōu)化, 最重要的是使用簡(jiǎn)單, 通過(guò)鏈?zhǔn)秸Z(yǔ)法輕松寫出一篇圖文混排文本.
示例說(shuō)明
如圖所示一篇圖文混排, 涉及到字體, 顏色, 字間距, 行間距, 圖片對(duì)齊, 文字對(duì)齊, 描邊等等屬性, 還有網(wǎng)絡(luò)圖片與本地圖片混排, 手勢(shì)響應(yīng)等需求, 使用本框架可以下面這樣實(shí)現(xiàn):
????//...省略常量聲明 ????//標(biāo)題 ????title.font(titleFont).color(titleColor).onClicked(titleOnClicked).onLayout(titleOnLayout); ????//首段 ????firstPara.color(firstParaColor).align(@0); ????//圖片需要用一個(gè)空字符串起頭 ????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); ???? ????//設(shè)置全局默認(rèn)屬性,?優(yōu)先級(jí)低于指定屬性 ????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) ????//設(shè)置默認(rèn)屬性 ????.append(defaultAttributes) ????//繪制View ????.drawView(^(UIView?*drawView)?{ ????????[self.view?addSubview:drawView]; ????});
甚至可以這樣實(shí)現(xiàn):
????//...省略常量聲明 ????@"" ????//拼接全文 ????.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) ????//設(shè)置默認(rèn)屬性 ????.entire().maxSize(maxSize).align(@2).letterSpace(@3).minLineHeight(@20).maxLineHeight(@20).imageAlign(@1).onClicked(textOnClicked).imageSize(imageSize) ????//繪制 ????.drawView(^(UIView?*drawView)?{ ????????[self.view?addSubview:drawView]; ????});
核心方法與屬性
對(duì) NSString 的擴(kuò)展
核心方法
-
append(id content)
拼接 content?可以是文本(NSString)、圖片(UIImage)、圖片鏈接(NSURL)(必須指定imageSize屬性)、視圖(CALayer/UIView)
-
entire()
設(shè)置整段富文本 優(yōu)先級(jí)低于指定屬性,?較為重要的屬性?maxSize?設(shè)置繪制約束,?部分段落屬性只在整段中設(shè)置生效
-
drawLayer(^(CALayer *drawLayer)completion)
繪制layer,?無(wú)法響應(yīng)手勢(shì)
-
drawView(^(UIView *drawView)completion)
繪制View,?可響應(yīng)手勢(shì)
屬性
通用屬性
-
verticalOffset 垂直偏移
-
onClicked 點(diǎn)擊回調(diào)
-
onLayout 展示回調(diào)
-
cacheFrame 緩存該段文本繪制位置
字符串屬性
-
font 字體: 文字字體/圖片居中對(duì)齊字體
-
color 顏色
-
letterSpace 字間距
-
strokeWidth 描邊寬度, 整數(shù)為鏤空, Color不生效; 負(fù)數(shù)Color生效
-
strokeColor 描邊顏色
-
verticalForm 文字繪制隨文字書寫方向, 默認(rèn) 否(0), 是(非0)
-
underline 下劃線類型, 整形, 0為none, 1為細(xì)線 2為加粗 9為雙條 參考 CTUnderlineStyle(僅枚舉了三種, 其他值也有不同效果)
圖片屬性
-
imageSize 圖片尺寸, 默認(rèn)為圖片本身尺寸, 會(huì)根據(jù)圖片縮放(2x 3x)自動(dòng)調(diào)整
-
imageAlign 圖片對(duì)齊模式, 0為默認(rèn), 基準(zhǔn)線對(duì)齊. 1為居中對(duì)齊至特定字體大小 參看 ZJTextImageAlign
段落屬性
-
maxSize 繪制的約束尺寸, 默認(rèn)不限制
-
minLineSpace 最小行間距
-
maxLineSpace 最大行間距
-
minLineHeight 最小行高
-
maxLineHeight 最小行高
-
align 對(duì)齊, 整形, 0為默認(rèn)靠左 1為靠右 2為居中, 參考 CTTextAlignment
-
lineBreakMode 對(duì)齊, 整形, 參考 NSLineBreakMode
性能
總體采用 CoreText + 異步繪制圖片完成, 理論上性能會(huì)比較高, 經(jīng)過(guò)測(cè)試如下數(shù)據(jù)供參考:
內(nèi)容: 一段文本加上兩張圖片
機(jī)型: iPhone 6
測(cè)試結(jié)果:
常規(guī)(使用NSAttributedString + UILabel)過(guò)程: 創(chuàng)建->顯示(繪制) 常規(guī)分析:
-
主線程代碼在 28ms 左右. (主線程代碼開(kāi)始 至 結(jié)束耗時(shí))
-
UILabel 顯示(繪制)耗時(shí)在 42ms 左右. (addSubview 至 drawRect 耗時(shí))
-
綜合耗時(shí) 70ms 左右, 全部在主線程
異步繪制(本框架)過(guò)程: 創(chuàng)建->異步繪制->顯示 異步繪制分析:
-
主線程(創(chuàng)建)代碼在 28ms 左右. (主線程代碼開(kāi)始 至 結(jié)束耗時(shí))
-
創(chuàng)建(主線程) + 異步繪制耗時(shí) 84ms 左右. (主線程代碼開(kāi)始 至 繪制出圖片回調(diào))
-
由 1、2 得出子線程繪制耗時(shí) 56ms 左右, 另外經(jīng)過(guò)多次試驗(yàn)(大段文字繪制)得出繪制復(fù)雜的段落也耗時(shí)增長(zhǎng)較少
-
顯示耗時(shí) 0.75 ms 左右. (addSubview 至 drawRect 耗時(shí))
-
綜合耗時(shí) 85ms 左右, 其中主線程 29ms, 子線程 56ms
結(jié)論:
-
相較于常規(guī)方式降低了主線程壓力 70ms -> 29ms
-
越復(fù)雜的文本收益越高(多控件合一, 異步繪制), 上圖中大段富文本繪制時(shí)間也只多了 15ms, 耗時(shí)增長(zhǎng)少
-
總體耗時(shí)增加了15ms, 都在子線程, 畢竟處理的邏輯比系統(tǒng)的多.
安裝
Github
Pod
pod?'ZJAttributedText'
本框架依賴 SDWebImage (幾乎所有App都集成了, 可以共用一套緩存邏輯)
尾巴
內(nèi)部實(shí)現(xiàn)代碼不多, 幾乎所有步驟都添加了注釋, 如果需要學(xué)習(xí) CoreText, 異步繪制, 鏈?zhǔn)秸Z(yǔ)法, 還算是個(gè)不錯(cuò)的 Demo, 如果大家感興趣, 可以補(bǔ)充下 CoreText 相關(guān)內(nèi)容, 這部分網(wǎng)上的資料都比較老, 錯(cuò)誤也比較多. 歡迎 issue 與 star~
- PSoC NeoPixel Easy輕量級(jí)庫(kù)
- YYText iOS文本框架
- 輕量級(jí)的媒體框架引擎組件HiStreamer 1次下載
- 原創(chuàng)分享:自制輕量級(jí)單片機(jī)UI框架
- 輕量級(jí)的SDN數(shù)據(jù)包轉(zhuǎn)發(fā)驗(yàn)證方案 10次下載
- 基于Feistel結(jié)構(gòu)的超輕量級(jí)分組密碼算法 4次下載
- 基于輕量級(jí)虛擬化的LDDoS仿真攻防方法 6次下載
- 基于YOLO改進(jìn)的輕量級(jí)交通標(biāo)識(shí)檢測(cè)模型 12次下載
- 一種輕量級(jí)時(shí)間卷積網(wǎng)絡(luò)設(shè)計(jì)方案 6次下載
- Protothreads極輕量級(jí)系統(tǒng)的詳細(xì)資料簡(jiǎn)介
- C#教程之自制數(shù)值文本框組件 10次下載
- 基于ARM的輕量級(jí)TCPIP協(xié)議棧的移植及應(yīng)用 54次下載
- 基于MVC架構(gòu)的輕量級(jí)工作流引擎設(shè)計(jì) 0次下載
- 輕量級(jí)工作流引擎架構(gòu)設(shè)計(jì) 0次下載
- 輕量級(jí)RFID安全協(xié)議 22次下載
- 嵌入式框架Zorb Framework狀態(tài)機(jī)的實(shí)現(xiàn) 1207次閱讀
- Linux輕量級(jí)工具集合Busybox的特點(diǎn)和使用 1449次閱讀
- 嵌入式框架Zorb Framework搭建方案 1494次閱讀
- 長(zhǎng)短距離循環(huán)更新(LRRU)網(wǎng)絡(luò)的輕量級(jí)深度網(wǎng)絡(luò)框架介紹 1084次閱讀
- 使用MVVM框架實(shí)現(xiàn)一個(gè)簡(jiǎn)單加法器 872次閱讀
- 一個(gè)輕量級(jí)的權(quán)限認(rèn)證框架:Sa-Token 2203次閱讀
- 一個(gè)純Python編寫的輕量級(jí)數(shù)據(jù)庫(kù) 856次閱讀
- 針對(duì)單片機(jī)開(kāi)發(fā)的輕量級(jí)OTA組件 1428次閱讀
- TinyDB輕量級(jí)數(shù)據(jù)庫(kù)有哪些特點(diǎn)呢 1504次閱讀
- 一款適合初學(xué)者超輕量級(jí)C語(yǔ)言網(wǎng)絡(luò)庫(kù)—Dyad 2015次閱讀
- 輕量級(jí)Kubernetes-K3S工具介紹 2532次閱讀
- 全球首款輕量級(jí)機(jī)械臂已經(jīng)出現(xiàn)了! 7535次閱讀
- spring框架中定時(shí)器使用與配置 1793次閱讀
- 谷歌開(kāi)發(fā)一個(gè)輕量級(jí)的庫(kù)——TFGAN 它可以讓生成對(duì)抗網(wǎng)絡(luò)更易于實(shí)驗(yàn) 5541次閱讀
- 什么是Hibernate?Hibernate框架架構(gòu)與框架原理分析 5313次閱讀
下載排行
本周
- 1山景DSP芯片AP8248A2數(shù)據(jù)手冊(cè)
- 1.06 MB | 532次下載 | 免費(fèi)
- 2RK3399完整板原理圖(支持平板,盒子VR)
- 3.28 MB | 339次下載 | 免費(fèi)
- 3TC358743XBG評(píng)估板參考手冊(cè)
- 1.36 MB | 330次下載 | 免費(fèi)
- 4DFM軟件使用教程
- 0.84 MB | 295次下載 | 免費(fèi)
- 5元宇宙深度解析—未來(lái)的未來(lái)-風(fēng)口還是泡沫
- 6.40 MB | 227次下載 | 免費(fèi)
- 6迪文DGUS開(kāi)發(fā)指南
- 31.67 MB | 194次下載 | 免費(fèi)
- 7元宇宙底層硬件系列報(bào)告
- 13.42 MB | 182次下載 | 免費(fèi)
- 8FP5207XR-G1中文應(yīng)用手冊(cè)
- 1.09 MB | 178次下載 | 免費(fèi)
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費(fèi)
- 2555集成電路應(yīng)用800例(新編版)
- 0.00 MB | 33566次下載 | 免費(fèi)
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費(fèi)
- 4開(kāi)關(guān)電源設(shè)計(jì)實(shí)例指南
- 未知 | 21549次下載 | 免費(fèi)
- 5電氣工程師手冊(cè)免費(fèi)下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費(fèi)
- 6數(shù)字電路基礎(chǔ)pdf(下載)
- 未知 | 13750次下載 | 免費(fèi)
- 7電子制作實(shí)例集錦 下載
- 未知 | 8113次下載 | 免費(fèi)
- 8《LED驅(qū)動(dòng)電路設(shè)計(jì)》 溫德?tīng)栔?/a>
- 0.00 MB | 6656次下載 | 免費(fèi)
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費(fèi)
- 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
- 78.1 MB | 537798次下載 | 免費(fèi)
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420027次下載 | 免費(fèi)
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費(fèi)
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費(fèi)
- 6電路仿真軟件multisim 10.0免費(fèi)下載
- 340992 | 191187次下載 | 免費(fèi)
- 7十天學(xué)會(huì)AVR單片機(jī)與C語(yǔ)言視頻教程 下載
- 158M | 183279次下載 | 免費(fèi)
- 8proe5.0野火版下載(中文版免費(fèi)下載)
- 未知 | 138040次下載 | 免費(fèi)
評(píng)論