需求如所示:左邊的是效果圖,右邊的是完成後的圖
解決過程:
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