Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 635|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-6-6 09:41:58 | 显示全部楼层 |阅读模式

    在提交数据发送网络请求,由于用户输入了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;
    }
    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-11 20:58 , Processed in 0.060340 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表