swift 聊天表情emoji转译——从键盘到输入框
Posted ihoudf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swift 聊天表情emoji转译——从键盘到输入框相关的知识,希望对你有一定的参考价值。
题记
做聊天框时,遇到了几个麻烦事,在此记录,以备自查,其他观者仅供参考。有更好的做法,也请赐教。
代码并不可直接复制使用。写博客时,添加了详细的注释,标明每段代码的用途。
正文
聊天输入框文字和表情输入,输入完后显示在聊天列表。
有几个麻烦的地方:
1、输入时表情转译。由图片转成[dog]。转译并不麻烦,关键是表情所在的位置。
2、显示到列表时的再转成表情。
3、图文混排
4、等等等等,很多小细节
逻辑1:点击表情键盘的一个表情后,如何显示到输入框里。
// 关键点:自定义一个attachment,用来存储表情的转译后的文字
class TalkfunAttachment: NSTextAttachment
var displayText: String?
// 点击表情键盘一个表情,获得表情名称,并显示到输入框
func appendImage(_ emoji: String)
guard let image = UIImage(named: emoji) else return
// 限制最大输入字符
if inputV.attributedText.length > 50
return
// 输入框内容不为空,发送按钮变颜色
self.sendBtn.backgroundColor = .hexColor("#1F9752")
// 记录光标位置,有可能从文字中插入表情
let currentLocation = inputV.selectedRange.location
// 构造图片富文本
let newH = 20.0
let newW = newH * image.size.width / image.size.height
let font = UIFont.systemFont(ofSize: 15)
let newY = roundf(Float(font.capHeight - newH))/2.0
let attach = TalkfunAttachment()
attach.displayText = "[\\(emoji)]" // 注意这里
attach.image = image
attach.bounds = CGRect(x: 0, y: Double(newY), width: newW, height: newH)
let imgStr = NSMutableAttributedString(attachment: attach)
// 获取输入框已有的内容
let oldStr = NSMutableAttributedString(attributedString: self.inputV.attributedText)
// 插入表情字符串
oldStr.insert(imgStr, at: currentLocation)
// 对整个内容设置UI属性
oldStr.addAttributes(self.getAttr(), range: NSMakeRange(0, oldStr.length))
// 赋值给输入框
self.inputV.attributedText = oldStr
// 让输入框高度随内容变化
fitSizeForTextView()
// 重新设置光标
inputV.selectedRange = NSMakeRange(currentLocation + imgStr.length, 0)
// 让输入框的高度随着内容而变化。最高110,最低50
func fitSizeForTextView()
let newHeight = inputV.sizeThatFits(CGSize(width: inputV.frame.size.width, height: inputV.frame.size.height)).height
var viewH = newHeight + 10 + 4
viewH = viewH < 50 ? 50 : viewH
if viewH > 110
viewH = 110
self.snp.updateConstraints (make) in
make.height.equalTo(viewH)
/// 输入框内容的富文本UI属性
private func getAttr() -> [NSAttributedString.Key : Any]
let style = NSMutableParagraphStyle()
style.lineSpacing = 2
let attr = [NSAttributedString.Key.paragraphStyle : style,
NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16),
NSAttributedString.Key.foregroundColor : UIColor.hexColor("#303030")
]
return attr
逻辑2:输入框有文字有图片,UITextView的text属性没有表情的信息,如何在添加了表情的输入框里继续追加文本呢。
// MARK: - delegate
// 为应对复制内容到文本框等情况,需要在此代理实时更新内容的富文本属性
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool
inputV.typingAttributes = getAttr()
return true
func textViewDidChange(_ textView: UITextView)
// 输入内容不是可选状态时去设置
if inputV.markedTextRange == nil || inputV.markedTextRange?.isEmpty ?? false
// 根据有无内容,设置发送按钮颜色
sendBtn.backgroundColor = inputV.attributedText.length > 0 ? .hexColor("#1F9752") : .hexColor("#CCCCCC")
let range = inputV.selectedRange
// 设置内容属性,并设置最大字符数
let attrText = NSMutableAttributedString(attributedString: inputV.attributedText)
attrText.addAttributes(getAttr(), range: NSRange(location: 0, length: attrText.length))
// 最大字符
if attrText.length > 50 // 限制最大长度
attrText.deleteCharacters(in: NSMakeRange(50, attrText.length - 50))
inputV.attributedText = attrText
inputV.selectedRange = range
// 根据内容设置输入框高度
fitSizeForTextView()
逻辑3:点击发送按钮,发送的是转译后的文字内容。如何解析输入框的文字和表情 得到最后的转译内容?例如:
输入框的内容显示的是:哈哈😄🌹,你好啊🌹
怎么得到:哈哈[haha][meigui],你好啊[meigui]
func getInputText() -> String?
// 获取输入框所有的内容
let returnStr = NSMutableAttributedString(attributedString: self.inputV.attributedText)
guard let attrText = self.inputV.attributedText else
return nil
// 最关键的地方:::
// 遍历attachment,用attachment的displayText去替换attachment。
// 把图片富文本换成转译后的文字内容,例如用[haha]替换😄
attrText.enumerateAttribute(NSAttributedString.Key.attachment, in: NSMakeRange(0, attrText.length), options: .reverse) value, range, _ in
if value is TalkfunAttachment
if let attach = value as? TalkfunAttachment, let emojiStr = attach.displayText
let newRange = NSMakeRange(range.location, range.length)
returnStr.replaceCharacters(in: newRange, with: emojiStr)
let text = returnStr.string
print("解析结束:" + text)
return text
结尾:
至此,我们完成从键盘点击表情 到点击发送 得到转译文字内容。
发送成功之后,如何解析文本,展示到聊天列表呢?请查看:
以上是关于swift 聊天表情emoji转译——从键盘到输入框的主要内容,如果未能解决你的问题,请参考以下文章