上一篇中对textField和textView等输入过滤的判断,后来我发现并不好,使用于苹果没有推出新表情。但是后来又发现,当输入法切换成九宫格时输入不了。然后查了下资料,发现了一个更好的方法,给大家分享下:
1、UITextField添加监听方法(UITextView不用此监听)
[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
2、输入时处理(
UITextView中string替换成text,textField替换成textView
,监听方法用- (void)textViewDidChangeSelection:(UITextView *)textView代替)
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string{
if ([self isInputRuleAndNumber:string] || [string isEqualToString:@""]){
return YES;
}else{
return NO;
}
}
//textField输入的监听方法:过滤表情等 和 限制输入字数
- (void)textFieldDidChange:(UITextField *)textField{
NSString *toBeString = textField.text;
NSString *lastString;
if(toBeString.length>0)
lastString=[toBeString substringFromIndex:toBeString.length-1];
if (![self isInputRuleAndNumber:toBeString]&&[self hasEmoji:lastString]) {
textField.text = [self disable_emoji:toBeString];
return;
}
//限制输入字数,如果没有该功能的下面的代码可以不要!
NSString *lang = [[textField textInputMode] primaryLanguage];
if([lang isEqualToString:@"zh-Hans"]) {
UITextRange *selectedRange = [textField markedTextRange];
UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
if(!position) {
NSString *getStr = [self getSubString:toBeString];
if(getStr && getStr.length > 0) {
textField.text = getStr;
}
}
}
else{
NSString *getStr = [self getSubString:toBeString];
if(getStr && getStr.length > 0) {
textField.text= getStr;
}
}
}
3、特殊文字处理、输入文本长度限制、过滤emoji表情
/**
* 字母、数字、中文
*/
- (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 >= 0x4e00 && a <= 0x9fa6))
||([other rangeOfString:str].location != NSNotFound)
))
return NO;
}
return YES;
}
/**
* 获得 kMaxLength长度的字符
*/
-(NSString *)getSubString:(NSString*)string
{
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSData* data = [string dataUsingEncoding:encoding];
NSInteger length = [data length];
//kMaxLength:文本输入数字限制
if (length > kMaxLength) {
NSData *data1 = [data subdataWithRange:NSMakeRange(0, kMaxLength)];
NSString *content = [[NSString alloc] initWithData:data1 encoding:encoding];//【注意4】:当截取kMaxLength长度字符时把中文字符截断返回的content会是nil
if (!content || content.length == 0) {
data1 = [data subdataWithRange:NSMakeRange(0, kMaxLength - 1)];
content = [[NSString alloc] initWithData:data1 encoding:encoding];
}
return content;
}
return nil;
}
/**
* 过滤字符串中的emoji
*/
- (BOOL)hasEmoji:(NSString*)str{
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:str];
return isMatch;
}
- (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;
}
*****************************************************************************
更新于:2016年11月9日
注:上面的方法会把输入法中的标点符号也过滤点!
有朋友私信我说怎么输入时打不了标点符号,标点符号也给过滤了。这里我再补充下怎么去掉过滤标点符号的出路:
1、下面的代理方法去掉
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
if ([self isInputRuleAndNumber:text] || [text isEqualToString:@""]){
return YES;
}else{
return NO;
}
}
2、输入的监听方法里 – (void)textViewDidChangeSelection:(UITextView *)textView; 稍微修改下
//输入的监听方法里 - (void)textViewDidChangeSelection:(UITextView *)textView;
if (![self isInputRuleAndNumber:toBeString]&&[self hasEmoji:lastString]) {
textView.text = [self disable_emoji:toBeString];
return;
}
//改成下面就可以了
if ([self hasEmoji:lastString]) {
textView.text = [self disable_emoji:toBeString];
return;
}
通过上面的两步操作便可以实现标点符号的输入。
如果有什么问题大家可以私信我,大家一块学习!