美文网首页iOS新手学习iOS 开发iOS开发
iOS限制输入表情(emoji),出现九宫格不能输入的解决方法

iOS限制输入表情(emoji),出现九宫格不能输入的解决方法

作者: 我是七月 | 来源:发表于2017-06-07 23:20 被阅读2738次
    奋斗的七月

    在提交数据发送网络请求,由于用户输入了emoji表情,服务端返回系统异常,体验感很差。为了解决服务器不能验证emoji编码的问题,需要在本地进行emoji的输入控制(一般情况应该由服务器在数据库中添加emoji对应的转码表以支持客户端发送emoji表情)。

    所以就有了这个需求:在TextField或者TextView中,限制输入任何表情符号,(包括系统自带的表情,第三方键盘带的表情,还有某些汉字类型的表情)。

    • 利用下面这个方法stringContainsEmoji可以限制系统键盘自带的表情
    /**
     *  判断字符串中是否存在emoji
     * @param string 字符串
     * @return YES(含有表情)
     */
    - (BOOL)stringContainsEmoji:(NSString *)string {
        
        __block BOOL returnValue = NO;
        
        [string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
         ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
             
             const unichar hs = [substring characterAtIndex:0];
             // surrogate pair
             if (0xd800 <= hs && hs <= 0xdbff) {
                 if (substring.length > 1) {
                     const unichar ls = [substring characterAtIndex:1];
                     const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                     if (0x1d000 <= uc && uc <= 0x1f77f) {
                         returnValue = YES;
                     }
                 }
             } else if (substring.length > 1) {
                 const unichar ls = [substring characterAtIndex:1];
                 if (ls == 0x20e3) {
                     returnValue = YES;
                 }
                 
             } else {
                 // non surrogate
                 if (0x2100 <= hs && hs <= 0x27ff) {
                     returnValue = YES;
                 } else if (0x2B05 <= hs && hs <= 0x2b07) {
                     returnValue = YES;
                 } else if (0x2934 <= hs && hs <= 0x2935) {
                     returnValue = YES;
                 } else if (0x3297 <= hs && hs <= 0x3299) {
                     returnValue = YES;
                 } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                     returnValue = YES;
                 }
             }
         }];
        
        return returnValue;
    }
    
    • 利用下面这个方法hasEmoji可以限制第三方键盘(常用的是搜狗键盘)的表情
    /**
     *  判断字符串中是否存在emoji
     * @param string 字符串
     * @return YES(含有表情)
     */
    - (BOOL)hasEmoji:(NSString*)string;
    {
        NSString *pattern = @"[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]";
        NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
        BOOL isMatch = [pred evaluateWithObject:string];
        return isMatch;
    }
    

    上面这2个方法就可以完全限制住键盘输入所有的表情。但是今天突然发现系统自带的键盘九宫格输入汉字不能使用了。

    最终发现当使用九宫格输入汉字时候,九宫格输入的本身就是表情,九宫格对应的是下面➋➌➍➎➏➐➑➒的字符。所有用上面2个方法就把这些表情限制了,导致不能输入汉字。

    既然找到了问题所在,那么开始撸代码:

    • 利用下面这个方法isNineKeyBoard可以判断当前是不是在使用九宫格输入
    /**
     判断是不是九宫格
     @param string  输入的字符
     @return YES(是九宫格拼音键盘)
     */
    -(BOOL)isNineKeyBoard:(NSString *)string
    {
        NSString *other = @"➋➌➍➎➏➐➑➒";
        int len = (int)string.length;
        for(int i=0;i<len;i++)
        {
            if(!([other rangeOfString:string].location != NSNotFound))
                return NO;
        }
        return YES;
    }
    
    

    下面就是现在UITextView禁止输入表情的重要代码,记得遵守代理~

    #pragma mark -------UITextViewDelegate
    -(BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
    {
        if ([textView isFirstResponder]) {
            
            if ([[[textView textInputMode] primaryLanguage] isEqualToString:@"emoji"] || ![[textView textInputMode] primaryLanguage]) {
                return NO;
            }
    
            //判断键盘是不是九宫格键盘
            if ([self isNineKeyBoard:text] ){
                    return YES;
            }else{
                if ([self hasEmoji:text] || [GeneralMethods stringContainsEmoji:text]){
                    return NO;
                }
            }
        }
        return YES;
    }
    
    

    UITextField在下面这个方法中写就行

    #pragma mark -----UITextFieldDelegate
    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    
    }
    

    另外附上几个有用的方法:
    //-----过滤字符串中的emoji
    - (NSString *)disable_emoji:(NSString *)text {
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]"options:NSRegularExpressionCaseInsensitive error:nil];
        NSString *modifiedString = [regex stringByReplacingMatchesInString:text
                                                                   options:0
                                                                     range:NSMakeRange(0, [text length])
                                                              withTemplate:@""];
        return modifiedString;
    }
    
    
    /**
     * 判断 字母、数字、中文
     */
    - (BOOL)isInputRuleAndNumber:(NSString *)str
    {
        NSString *other = @"➋➌➍➎➏➐➑➒";     //九宫格的输入值
        unsigned long len=str.length;
        for(int i=0;i<len;i++)
        {
            unichar a=[str characterAtIndex:i];
            if(!((isalpha(a))
                 ||(isalnum(a))
    //             ||((a=='_') || (a == '-')) //判断是否允许下划线,昵称可能会用上
                 ||((a==' '))                 //判断是否允许空格
                 ||((a >= 0x4e00 && a <= 0x9fa6))
                 ||([other rangeOfString:str].location != NSNotFound)
                 ))
                return NO;
        }
        return YES;
    }
    
    

    注意:上面这种方法可以限制键盘输入任何表情符号,但是如果需求是必须要输入表情,而且要下次服务器把这个表情返回,还要回显到页面上,就要看下面这篇文章

    彻底解决iOS输入表情,报系统异常问题

    相关文章

      网友评论

      • 王_胖胖:GeneralMethods stringContainsEmoji
        为啥这个方法要专门弄个类,其他都是self写在本类
        我是七月:@王_胖胖 项目中的,这个类中有很多公用方法!
      • macfai:楼主牛逼,给了我好的解决方案,这个表情还真是整了好久
      • BeyondChao:请问楼主这层循环貌似没用啊!
        for(int i=0;i<len;i++)
        {
        if(!([other rangeOfString:string].location != NSNotFound))
        return NO;
        }
      • 203c7880b37c::+1: :+1: 太感谢
        我是七月:@Vyron 😆哈哈
      • 啊哈呵:有个小问题:如果切换到表情输入,粘贴不了
        我是七月:这个问题,还一直没有注意过,有时间看下
      • Ilovecoding822:楼主威武,解决了,thx
        我是七月:@hippo_baby 哈哈😆,解决了就好
      • 口袋海贼王_:卤煮,现在已经八月了,你要改名字了。
        口袋海贼王_:@奋斗的七月 对头,这样你才能记得每个月都奋斗。
        我是七月:@口袋海贼王_ 哈哈,那我这一年要改12次名字啦:smile:
      • doubleJJ:赞~亲测有效,系统键盘自带的表情可以全部禁止,可是第三方键盘自带的表情有极个别的禁止不了,请问是什么原因呢?
        新_1740:@大铭 有个别的禁止不了,这个问题解决了吗?解决的话求分享
        大铭:@奋斗的七月 楼主这个问题解决了么
        我是七月:@doubleJJ 恩,这几天我也发现了,在搜狗键盘中,有两三个表情是禁止🚫不了,这个我暂时还没有解决,你如果解决了,告诉下😆😆😆

      本文标题:iOS限制输入表情(emoji),出现九宫格不能输入的解决方法

      本文链接:https://www.haomeiwen.com/subject/gvzafxtx.html