博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS TextFiled,TextView 长度限制,表情限制
阅读量:6158 次
发布时间:2019-06-21

本文共 11603 字,大约阅读时间需要 38 分钟。

需求:在文本框中限制输入表情,长度限制


实现原理: 通过这两个控件的代理与通知实现


阅读前提:

  • 由于搜狗等不断改善,可能小部分表情未能限制
  • 原理较为简单,不再讲解

Github:

简书地址 :

博客地址 :

掘金地址 :


注意

  1. 可以根据需求自行更改提示样式等等
  2. 可以根据需求自行优化过滤算法
  3. 好处:我们只需要有这样一个类,以后项目中所有需要限制的地方仅仅需要直接导入头文件,引用类方法即可

使用方法:

1. 导入头文件

#import "XDXTextContentHandler.h"复制代码

2. 直接在对应的代理或通知中对用头文件即可

- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.        self.testTextFiled.delegate = self;    self.testTextView.delegate  = self;        [[NSNotificationCenter defaultCenter] addObserver:self                                             selector:@selector(textFiledEditChanged:)                                                 name:@"UITextFieldTextDidChangeNotification"                                               object:self.testTextFiled];}#pragma mark - Notification- (void)textFiledEditChanged:(NSNotification *)obj {    [XDXTextContentHandler handleTextFiledEditChangedWithNotification:obj textMaxLength:kTitleTextMaxLength isShowTip:YES];}#pragma mark - Delegate#pragma mark TextFiled- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {    return [XDXTextContentHandler handleTextFiledShouldChangeTextInRangeWithTextFiled:textField range:range replacementText:string isShowTip:YES];}#pragma mark TextView- (void)textViewDidChange:(UITextView *)textView {    [XDXTextContentHandler handleTextViewDidChangeWithTextView:textView textMaxLength:kTitleTextMaxLength isShowTip:YES];}- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {    return [XDXTextContentHandler handleTextViewShouldChangeTextInRangeWithTextView:textView range:range replacementText:text isShowTip:YES];}复制代码

具体实现:

  • 长度限制:即检测到超过设定长度后截取字符串
  • 表情限制:检测是苹果自带还是第三方,过滤关键字
@implementation XDXTextContentHandler#pragma mark - Public Main Func+ (void)handleTextFiledEditChangedWithNotification:(NSNotification *)notification textMaxLength:(int)textMaxLength isShowTip:(BOOL)isShowTip {    UITextField *textField  = (UITextField *)notification.object;    if ([textField isFirstResponder]) {        NSString *toBeString = textField.text;        if (toBeString.length > textMaxLength) {            textField.text = [toBeString substringToIndex:textMaxLength];                        if (isShowTip) {                [self showAlertVCWithTitle:@"Warning" message:[NSString stringWithFormat:@"Text max length is %d",textMaxLength]];            }        }    }}+ (void)handleTextViewDidChangeWithTextView:(UITextView *)textView textMaxLength:(int)textMaxLength isShowTip:(BOOL)isShowTip {    if ([textView isFirstResponder]) {        if (textView.text.length > textMaxLength) {            textView.text = [textView.text substringToIndex:textMaxLength];            if (isShowTip) {                [self showAlertVCWithTitle:@"Warning" message:[NSString stringWithFormat:@"Text max length is %d",textMaxLength]];            }        }    }        NSString *toBeString = textView.text;        if (![self isInputRuleAndBlank:toBeString]) {        textView.text = [self disable_emoji:toBeString];                if (isShowTip) {            [self showAlertVCWithTitle:@"Warning" message:[NSString stringWithFormat:@"Not input emoji"]];        }        return;    }        NSString *lang = [[textView textInputMode] primaryLanguage]; // 获取当前键盘输入模式    NSLog(@"%@",lang);    if([lang isEqualToString:@"zh-Hans"]) { //简体中文输入,第三方输入法(搜狗)所有模式下都会显示“zh-Hans”        UITextRange *selectedRange = [textView markedTextRange];        //获取高亮部分        UITextPosition *position = [textView positionFromPosition:selectedRange.start offset:0];        //没有高亮选择的字,则对已输入的文字进行字数统计和限制        if(!position) {            NSString *getStr = [self getSubString:toBeString textMaxLength:textMaxLength];            if(getStr && getStr.length > 0) {                textView.text = getStr;            }        }    } else{        NSString *getStr = [self getSubString:toBeString textMaxLength:textMaxLength];        if(getStr && getStr.length > 0) {            textView.text= getStr;        }    }}+ (BOOL)handleTextViewShouldChangeTextInRangeWithTextView:(UITextView *)textView range:(NSRange)range replacementText:(NSString *)text isShowTip:(BOOL)isShowTip {    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] || [self stringContainsEmoji:text]){                if (isShowTip) {                    [self showAlertVCWithTitle:@"Warning" message:[NSString stringWithFormat:@"Not input emoji"]];                }                return NO;            }        }    }    return YES;}+ (BOOL)handleTextFiledShouldChangeTextInRangeWithTextFiled:(UITextField *)textFiled range:(NSRange)range replacementText:(NSString *)text isShowTip:(BOOL)isShowTip {    if ([textFiled isFirstResponder]) {        if ([[[textFiled textInputMode] primaryLanguage] isEqualToString:@"emoji"] || ![[textFiled textInputMode] primaryLanguage]) {            if (isShowTip) {                [self showAlertVCWithTitle:@"Warning" message:[NSString stringWithFormat:@"Not input emoji"]];            }            return NO;        }                //判断键盘是不是九宫格键盘        if ([self isNineKeyBoard:text]){            return YES;        }else{            if ([self hasEmoji:text] || [self stringContainsEmoji:text]){                if (isShowTip) {                    [self showAlertVCWithTitle:@"Warning" message:[NSString stringWithFormat:@"Not input emoji"]];                }                return NO;            }        }    }    return YES;}#pragma mark - Private#pragma mark TextView禁止表情相关// 字母、数字、中文常用字符正则判断(不包括空格)+ (BOOL)isInputRuleNotBlank:(NSString *)str {    NSString *pattern = @"^[a-zA-Z,.!@#$%^:;\\=+-_()¥。“、\u4E00-\u9FA5\\d\\n]*$";    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];    BOOL isMatch = [pred evaluateWithObject:str];    return isMatch;}// 字母、数字、中文正则判断(包括空格)(在系统输入法中文输入时会出现拼音之间有空格,需要忽略,当按return键时会自动用字母替换,按空格输入响应汉字)+ (BOOL)isInputRuleAndBlank:(NSString *)str {    NSString *pattern = @"^[a-zA-Z\u4E00-\u9FA5\\d\\s]*$";    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];    BOOL isMatch = [pred evaluateWithObject:str];    return isMatch;}// 获得 kIntroTextViewMaxLength长度的字符+ (NSString *)getSubString:(NSString*)string textMaxLength:(int)textMaxLength {    NSStringEncoding encoding   = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);    NSData           *data      = [string dataUsingEncoding:encoding];    NSInteger        length     = [data length];    if (length > textMaxLength) {        NSData *data1 = [data subdataWithRange:NSMakeRange(0, textMaxLength)];        NSString *content = [[NSString alloc] initWithData:data1 encoding:encoding];//注意:当截取kIntroTextViewMaxLength长度字符时把中文字符截断返回的content会是nil        if (!content || content.length == 0) {            data1 = [data subdataWithRange:NSMakeRange(0, textMaxLength - 1)];            content =  [[NSString alloc] initWithData:data1 encoding:encoding];        }        return content;    }    return nil;}+ (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;}/** *  判断字符串中是否存在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;}/** 判断是不是九宫格 @param string  输入的字符 @return YES(是九宫格拼音键盘) */-(BOOL)isNineKeyBoard:(NSString *)string {    NSString *other = @"➋➌➍➎➏➐➑➒";    int len = (int)string.length;    for(int i=0;i
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;}+ (void)showAlertVCWithTitle:(NSString *)title message:(NSString *)message { UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *OKAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) style:UIAlertActionStyleDefault handler:nil]; [alertVC addAction:OKAction]; UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController; [rootVC presentViewController:alertVC animated:YES completion:nil];}@end复制代码

转载于:https://juejin.im/post/5c9382f7f265da60df41074e

你可能感兴趣的文章
Ubuntu unity安装Indicator-Multiload
查看>>
解决Eclipse中新建jsp文件ISO8859-1 编码问题
查看>>
7.对象创建型模式-总结
查看>>
【论文阅读】Classification of breast cancer histology images using transfer learning
查看>>
移动端处理图片懒加载
查看>>
jQuery.on() 函数详解
查看>>
谈缓存和Redis
查看>>
【转】百度地图api,根据多点注标坐标范围计算地图缩放级别zoom自适应地图
查看>>
用户调研(补)
查看>>
ExtJS之开篇:我来了
查看>>
☆1018
查看>>
oracle 去掉空格
查看>>
6.13心得
查看>>
Runtime类
查看>>
eclipse decompiler
查看>>
记一个搜索网盘资源的网站
查看>>
jdk1.7和jdk1.8的String的getByte方法的差异
查看>>
java父子进程通信
查看>>
Android ADB server didn't ACK * failed to start daemon * 简单有效的解决方案
查看>>
Olap学习笔记
查看>>