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

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

  • 利用下面这个方法stringContainsEmoji可以限制系统键盘自带的表情
  1. /**
  2. * 判断字符串中是否存在emoji
  3. * @param string 字符串
  4. * @return YES(含有表情)
  5. */
  6. - (BOOL)stringContainsEmoji:(NSString *)string {
  7. __block BOOL returnValue = NO;
  8. [string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
  9. ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
  10. const unichar hs = [substring characterAtIndex:0];
  11. // surrogate pair
  12. if (0xd800 <= hs && hs <= 0xdbff) {
  13. if (substring.length > 1) {
  14. const unichar ls = [substring characterAtIndex:1];
  15. const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
  16. if (0x1d000 <= uc && uc <= 0x1f77f) {
  17. returnValue = YES;
  18. }
  19. }
  20. } else if (substring.length > 1) {
  21. const unichar ls = [substring characterAtIndex:1];
  22. if (ls == 0x20e3) {
  23. returnValue = YES;
  24. }
  25. } else {
  26. // non surrogate
  27. if (0x2100 <= hs && hs <= 0x27ff) {
  28. returnValue = YES;
  29. } else if (0x2B05 <= hs && hs <= 0x2b07) {
  30. returnValue = YES;
  31. } else if (0x2934 <= hs && hs <= 0x2935) {
  32. returnValue = YES;
  33. } else if (0x3297 <= hs && hs <= 0x3299) {
  34. returnValue = YES;
  35. } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
  36. returnValue = YES;
  37. }
  38. }
  39. }];
  40. return returnValue;
  41. }
  • 利用下面这个方法hasEmoji可以限制第三方键盘(常用的是搜狗键盘)的表情
  1. /**
  2. * 判断字符串中是否存在emoji
  3. * @param string 字符串
  4. * @return YES(含有表情)
  5. */
  6. - (BOOL)hasEmoji:(NSString*)string;
  7. {
  8. NSString *pattern = @"[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]";
  9. NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
  10. BOOL isMatch = [pred evaluateWithObject:string];
  11. return isMatch;
  12. }

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

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

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

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

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

  1. #pragma mark -------UITextViewDelegate
  2. -(BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
  3. {
  4. if ([textView isFirstResponder]) {
  5. if ([[[textView textInputMode] primaryLanguage] isEqualToString:@"emoji"] || ![[textView textInputMode] primaryLanguage]) {
  6. return NO;
  7. }
  8. //判断键盘是不是九宫格键盘
  9. if ([self isNineKeyBoard:text] ){
  10. return YES;
  11. }else{
  12. if ([self hasEmoji:text] || [GeneralMethods stringContainsEmoji:text]){
  13. return NO;
  14. }
  15. }
  16. }
  17. return YES;
  18. }

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

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

另外附上几个有用的方法:
  1. //-----过滤字符串中的emoji
  2. - (NSString *)disable_emoji:(NSString *)text {
  3. 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];
  4. NSString *modifiedString = [regex stringByReplacingMatchesInString:text
  5. options:0
  6. range:NSMakeRange(0, [text length])
  7. withTemplate:@""];
  8. return modifiedString;
  9. }
  1. /**
  2. * 判断 字母、数字、中文
  3. */
  4. - (BOOL)isInputRuleAndNumber:(NSString *)str
  5. {
  6. NSString *other = @"➋➌➍➎➏➐➑➒"; //九宫格的输入值
  7. unsigned long len=str.length;
  8. for(int i=0;i<len;i++)
  9. {
  10. unichar a=[str characterAtIndex:i];
  11. if(!((isalpha(a))
  12. ||(isalnum(a))
  13. // ||((a=='_') || (a == '-')) //判断是否允许下划线,昵称可能会用上
  14. ||((a==' ')) //判断是否允许空格
  15. ||((a >= 0x4e00 && a <= 0x9fa6))
  16. ||([other rangeOfString:str].location != NSNotFound)
  17. ))
  18. return NO;
  19. }
  20. return YES;
  21. }

iOS限制输入表情(emoji),出现九宫格不能输入的解决方法的更多相关文章

  1. IOS开发证书变成“此证书的签发者无效”解决方法

    IOS开发证书全部变成无效,如下图  打包提示错误  解决方法: 1. 下载https://developer.apple.com/certificationauthority/AppleWWDRCA ...

  2. ios/iphone手机请求微信用户头像错位BUG及解决方法

    转:http://www.jslover.com/code/527.html ios/iphone手机请求微信用户头像错位BUG及解决方法 发布时间:2014-12-01 16:37:01 评论数:0 ...

  3. JS 控制输入框输入表情emoji 显示在页面上

    问题描述: 最近做一个评论回复的功能遇到了用户输入框输入表情,存入数据库的时候转变成了问号??? 起初为了避免这个问题,做了一个过滤表情的控制 var inputText = $('#pinglun' ...

  4. ios svn无法连接xp或者win7系统svn的解决方法

    找到服务器svn的安装目录,或者直接查找httpd.conf,找到端口号,复制到ios系统的svn端口号,就ok了,如图 这是其他人的解决方法 Subversion有两种不同的配置方式,一种基于它自带 ...

  5. IDEA下搜狗输入法输入中文时卡着不动的参考解决方法

    在IntelliJ IDEA工具的java编辑窗口,给代码增加注释时发现,输入中文时,搜狗输入法界面不动,一直卡着,如图:  我想输入“根据”两个字,但搜狗输入法界面一直卡着不刷新,导致都不知道自己输 ...

  6. Ubuntu VNC 打开spyder无法输入(检测不到键盘配置)解决方法

    在ubuntu中安装好spyder后, 打开spyder发现无法输入. 在打开spyder的终端窗口,有如下提示: QXcbConnection: Failed to initialize XRand ...

  7. JavaSwing输入对话框,点击取消抛出异常的解决方法

    在做产品管理系统的时候,遇到一个问题: 在得到一个输入框对话框的时候 String textPrice = JOptionPane.showInputDialog("请输入要调整的价格增(减 ...

  8. iOS UITableViewCell点击时子视图背景透明的解决方法

    在做iOS项目的开发中,UITableView控件的应用十分广泛.在进行自定义UITableViewCell时,经常遇到这样的问题:在UITableViewCell上面添加了一个有背景颜色的子视图,当 ...

  9. Linux下忘记MySQL密码的解决方法和输入mysqld_safe --skip-grant-tables &后无法进入MySQL的解决方法

    在Linux下忘记MySQL密码后我们可以通过一个mysql的参数--skip-grant-tables &轻松解决这个问题 亲测在CentOS有效 其中 --skip-grant-table ...

随机推荐

  1. rocketMQ基本理解

    消息中间件需要解决哪些问题? Publish/Subscribe 发布订阅是消息中间件的最基本功能,也是相对于传统RPC通信而言. Message Priority 规范中描述的优先级是指在一个消息队 ...

  2. LeetCode——Integer Replacement

    Question Given a positive integer n and you can do operations as follow: If n is even, replace n wit ...

  3. Tachyon:Spark生态系统中的分布式内存文件系统

    转自: http://www.csdn.net/article/2015-06-25/2825056  摘要:Tachyon把内存存储的功能从Spark中分离出来, 使Spark可以更专注计算的本身, ...

  4. 自学Java测试代码一数据类型、数组使用

    2017-08-22 21:23:37. writer:pprp package test; public class helloWorld { int maxn = 123; //常量,需要定义一个 ...

  5. C4 文件和目录:APUE 笔记

    C4: 文件和目录 本章主要讨论stat函数及其返回信息,通过修改stat结构字段,了解文件属性. struct stat结构定义如下: struct stat { __dev_t st_dev; / ...

  6. 运行UART的程序

    1 捎程序的时候,注意,捎入的是norflash,此时的按钮应该在norFlash.2 当捎入成功的时候,开始运行程序时,应该把按钮按回nandflash,因为程序的启动就是在nandflash,他把 ...

  7. iOS开发调试技巧总结(持续更新中)

    作者:乞力马扎罗的雪  原文 对于软件开发而言,调试是必须学会的技能,重要性不言而喻.对于调试的技能,基本上是可以迁移的,也就是说你以前在其他平台上掌握的很多调试技巧,很多也是可以用在iOS开发中.不 ...

  8. MySQLdb和PIL安装

    最近将个人博客部署到树莓派上海真是颇费周折,尤其是在MySQLdb和PIL的安装上 MySQLdb 先说Windows吧(比较简单) 直接pip安装即可或者下载编译版更方便:http://source ...

  9. Math Issues

    Oh no, our Math object was "accidently" reset. Can you re-implement some of those function ...

  10. 探究JS中的连等赋值问题

    一.引子 最近在看别人的博客时无意中看到一个这样的问题 var a = {n: 1}; var b = a; a.x = a = {n:2}; console.log(a.x); //undefine ...