前篇講完佈局,這篇講講我卡住最久的部分,想流暢地在打字時插入自訂的表情符號,一開始是有些目標錯誤,因為使用者有各種各自習慣的鍵盤,所以就一直針對個鍵盤的特性去攔截使用者正在打的字(使用”textView(_:shouldChangeTextIn:replacementText:)”),後來覺得這樣會沒完沒了,改變思路找到了NSMutableAttributedString,完全能解決我的問題,所以想把這個解法好好跟大家分享一樣,雖然大神們可能有更好的解法,但就讓我獻醜一下:)
TextField、Label、TextView都有attributedText可以選用,都可以達成圖文混排的效果,但這邊我的打字框和對話框全都是用TextView元件來達成。
在打字框打完字,按下送出鍵經由socket發送,有兩個方向要去處理:
1.socket要傳送的訊息
2.聊天室的顯示框訊息
第1點socket要傳送的訊息通常傳純文字就可以了,只要圖片套入的圖片後台對的到就ok了,所以先把訊息處理成純文字,存成strA(String),然後再把strA處理成strB(NSMutableAttributedString)
第2點處理文字和圖片的組合訊息時的邏輯是這樣的(雖然好像有點笨?♀️,但我的確是有成功的)
首先把輸入的String訊息抓出是否有”<img src=\"images/emo/”或"\" />”
將其替換成否個特殊符號,然後再依特殊符號來分隔資料存成新陣列,然後用迴圈篩選新陣列裡有無.gif
假如有.gif就把他替換成空字串,然後再將它處理成顯示app裡該檔名的圖片加到結果陣列中
假如沒有.gif就直接把它轉型成NSAttributedString然後加到結果陣列中
範例代碼如下
let str = “測試表情符號?”
/***換成app內圖片*/
func myImageStringHandle(_ str: String) -> NSMutableAttributedString {
//separatedBy:的判斷會讓判斷值消失,故塞了一個無法用鍵盤打出得值替代
let newStr1 = str.replacingOccurrences(of: "\" />", with: "㊟")
let newStr2 = newStr1.replacingOccurrences(of: "<img src=\"images/emo/", with: "㊟")
//newStr2會印出”測試表情符號㊟19.gif㊟”
let mixArr = newStr2.components(separatedBy: "㊟")
//mixArr會印出”[“測試表情符號", "19.gif", “”]”
let strB = NSMutableAttributedString()
for i in 0..<mixArr.count {
if mixArr[i].contains(".gif") {
// 為圖片 需去除.gif 後提供
let handleStr = mixArr[i].replacingOccurrences(of: ".gif", with: "")
//handleStr會印出”19”
strB.append(createAttachment(handleStr))
//strB會印出”測試表情符號{}{NSAttachment = "<NSTextAttachment: 0x7f91f15a2050>”;}”
}
else {
let attrString = NSAttributedString(string: mixArr[i])
//attrString會印出”測試表情符號{}”
strB.append(attrString)
//strB會印出”測試表情符號{}”
}
}
//strB最終會印出”測試表情符號{}{NSAttachment = "<NSTextAttachment: 0x7f91f15a2050>”;}”
return strB
}