Tips:
最近做的项目中有个朋友圈的功能模块,其中评论和创建动态中需要输入文本。这两个文本按照正常的逻辑都是可以输入表情的,奈何数据库设计的时候设计成有限制的 varchar 类型,因为字数有限制,所以想支持表情存储,就需要把用户输入的内容转换成 Base64 编码的字符串传给后台,后台再存入数据库,取的时候移动端只需要进行 Base64 解码即可正常显示。但是 Base64 编码的字符串是把一个字符转换成像 6FB4 这种字符串,然而数据库因为是 varchar 类型的字段所以存储不了想要达到的最大字符限制,而且后台的小伙伴们又不想改数据库字段类型,所以只能由移动端来背锅。所以就有了限制表情输入的操蛋设定。
判断一个字符是否是表情
判断是否是表情就是一个难点,百度了好多天也没有找到能完全覆盖最新的众多表情的方法。所以就想到有没有第三方库包含这个方法。
下面隆重推荐下 github 上的一个 Swift 第三方库 SwifterSwift,项目中我使用的是版本 3.0(写这篇文章时)
其中有个 Character
的扩展布尔属性就是判断是否是表情:isEmoji
。
移除字符串中的表情符号
基于项目需要,自己结合这个扩展属性写了个扩展方法:
public extension String {
/// 移除字符串中的表情符号,返回一个新的字符串
public func removeEmoji() -> String {
return self.characters.reduce("") {
if $1.isEmoji {
return $0 + ""
} else {
return $0 + String($1)
}
}
}
}
在项目中使用该扩展方法
1.先说下 UITextView
中怎样限制表情输入。首先要设置 UITextView
的代理,使用 textViewDidChange(_ textView: UITextView)
方法:
func textViewDidChange(_ textView: UITextView) {
// 获取高亮部分,中文输入时预输入的拼音也输入高亮部分
// 所以中文输入的时候,markedTextRange 是存在的
// 这时候应该忽略
guard textView.markedTextRange == nil else { return }
var string = textView.text ?? ""
// 移除字符串中的表情符号
string = string.removeEmoji()
// 判断时候大于字符数量限制
if string.characters.count > limit {
string = string.substring(start: 0, length: limit)
}
// 把经过移除表情和移除多余字符的字符串赋值给 textView
textView.text = string
// limitLabel: 显示剩余可输入字符长度的文本框
limitLabel.text = "\(limit - string.characters.count)"
}
Tips:
网上有很多人用到
textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool
这个方法,在这个方法中去判断是否是表情,然后去限制表情的输入,这里是存在BUG的,因为当使用系统九宫格中文输入法时,在这个方法里获取的到text
是表情字符,对应按钮的表情是➋、➌、➍、➎、➏、➐、➑、➒、☻(旁边的笑脸按钮)。所以在这里判断是表情,返回 false,那么九宫格中文输入就输入不了。