一個圖文混排問題的解決過程


需求如所示:左邊的是效果圖,右邊的是完成后的圖

               

具體需求描述:用戶的回復一條就是一個cell,字數不定。當存在某種條件時,需要在文字(可能換行)的最后一個字后面添加一個能點擊的刪除按鈕小圖標,文字支持emoji表情符號。

解決過程:

1、一看到這種文字中需要穿插圖片的就想到了富文本中的NSTextAttachment對象,它可以包裝一個image后生成一個富文本,再給UILabel顯示就能完成顯示需求,但是,該對象只能包裝UIImage對象,無法監聽圖片的點擊事件,不符合要求。

2、富文本是個好的思路,NSTextAttachment差就差在無法包裝UIView對象。於是找到了YYKit框架,上面有個方法能包裝UIView對象生成一個富文本對象

經試驗,該富文本對象無法用UILabel和UITextView顯示,只能用YYLabel顯示,而YYlabel繼承自UIView,當富文本對象中有emoji表情時,其渲染方式/位置和UILabel有所差別,導致用NSString的boundingRectWithSize方法計算出來的YYLabel高度不對,當存在emoji表情時,經常出現...的顯示不全現象,多方試驗無果,放棄

3、第一種方法是能完成顯示效果的,只是無法監聽點擊事件。於是找到了種方法,能計算UILabel最后一個字的右上角坐標,於是一個想法產生了:在這個位置添加一個看不見的按鈕監聽事件。計算位置方法如下

sz是計算文本不換行狀態下單行的尺寸,linesSz是計算文本在換行狀態下的尺寸。

通過在算出位置添加一個較大的看不見的按鈕監聽點擊事件,大部分情況是可行的。但是,此方法有時候算出的結果不准確,且需要考慮所添加按鈕超出邊界顯示不全的情況,也無法達到所需版本要求。

4、沒轍,准備學習萬惡的CoreText。看着看着,發現了CoreText的封裝版本TextKit,OC接口的,頓時順心了。TextKit主要就三個類: NSTextStorage用來保存需要顯示的文本及相關屬性, NSLayoutManager用來決定文本顯示的格式, NSTextContainer決定文本顯示的范圍。這個主要能解決連接高亮、下划線、文字標記、區域顯示等問題,對此問題也沒有幫助

5、最后,好友提示了UITextView的一個方法,selectionRectsForRange,能夠得到選中字符串的CGRect,於是問題得到了解決。

這段代碼的意思就是,拿到textView的最后兩個字范圍,在上面添加一個按鈕來監聽點擊事件。

這段代碼就是在用戶發言的文字后面添加一個透明的字符串,用來參與高度計算等,注意,該占位符不能使用數字和空格,必須用字符代替空格(主要是兼容emoji表情)。

針對TextView,采用其所顯示的文字計算寬高,設置textView的size需要注意:

a、計算textView文本時,計算寬度需要比textView本身的寬度減少8

b、 textView高度必須比文字高度多2 * 8 的額外高度

 github地址:https://github.com/zhangmaliang/AddDeleteButton

 

補充: 無意中發現TextView代理方法能監聽文本附件的事件交互,用第一種方法就可以了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM