Swift:UITextView 限制表情输入

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,那么九宫格中文输入就输入不了。

你可能感兴趣的:(Swift:UITextView 限制表情输入)