iOS UITextField 输入限制字符,并截取限制位置的字符

由于PM的需求,进行输入字符数限制,需(wen)求(ti)如下:
1.如何进行判断当前是否是字母、数字、还是中文
2.中文占用2个字符,而英文是1个字符,这样当输入汉字时,限制80个字符,只能输入40个汉字
3.判断字符串长度后进行限制字符截取,
这个时候问题来了,你需要进行判断当前输入的长度,这个可以也可以通过转换 判断当前是中文就进行2个字符的判断,没有问题
我先用的方法如下
UITextField进行监听

 [textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

如果当前输入框进行编辑的时候进行监听
方法实现如下:

- (void)textFieldDidChange:(UITextField *)textField{
        NSString *toBeString = textField.text;
        NSString *lang = [[UITextInputMode currentInputMode] primaryLanguage]; // 键盘输入模式
        if ([lang isEqualToString:@"zh-Hans"]) { // 简体中文输入,包括简体拼音,健体五笔,简体手写
            UITextRange *selectedRange = [textField markedTextRange];
            //获取高亮部分
            UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
            // 没有高亮选择的字,则对已输入的文字进行字数统计和限制
            if (!position) {
                if ([toBeString lengthForChineseAndEnglish] > 40) {
                    textField.text = [toBeString substringToIndex:40];
                    AlertShow(@"最多只能输入40中文!");
                }
            }
            // 有高亮选择的字符串,则暂不对文字进行统计和限制
            else{
                
            }
        }
        // 中文输入法以外的直接对其统计限制即可,不考虑其他语种情况
        else{
            if ([toBeString lengthForChineseAndEnglish] > 80) {
                textField.text = [toBeString substringToIndex:80];
                AlertShow(@"最多只能输入80字符");
            }
        }
}

字符串中英文判断长度

#pragma mark - 字符串中英文长度方法
- (NSUInteger)lengthForChineseAndEnglish
{
    NSInteger length = 0;
    NSString *str = self;
    for (NSUInteger i = 0; i < [str length]; i++) {
        unichar ch = [str characterAtIndex:i];
        if (ch > 128) {
            length += 2;
        } else {
            length += 1;
        }
    }
    return length;
}

上面方法实现原理:首先根据当前键盘进行判断 如果是键盘是中文,就让限制数除以2进行判断

这个方案有个弊端就是当前键盘是简体中文,而你输入的却是字母或者数字,此时通过判断字符长度是根据中文的长度来判断的,只能截取40个中文或者字母、数字

PM的需求不是这样的 要40个中文,或者80个字母、数字

FUCK,看来是自己的判断有问题,查资料修改,最后问了Android同事如何判断的,告诉我转换成GBK2312也就是NSData的数据,进行判断 然后截取

解决的方法原理:输入的不管是中文、字母、数字、还是中英文混合,进行判断字符数的时候有个错误就是输入的东西转换成统一的,进行字符判断,截取是限制的字符。
开始着手进行转换
首先NSString转换成成NSData形式
NSData *data = [toBeString dataUsingEncoding:NSUTF8StringEncoding];
判断完字符串截取然后NSData转成NSString形式
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
发现字符串是空的,查了好多资料才只能,NSData通过NSUTF8StringEncoding转字符串的时候带中文的标点符号转过来是空的
My God 只能硬着头皮一个一个试了
最后查到转成GBK2312格式 在转成字符串就可以了

正确的设置方法如下

- (void)textFieldDidChange:(UITextField *)textField{
    NSString *toBeString = textField.text;
    int maxLengh = 500;
    toBeString = [toBeString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    NSString *message = [NSString stringWithFormat:@"当前内容最多限制%d个字符",maxLengh];
    NSStringEncoding stringEncoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingEUC_CN);
   UITextRange *markedTextRange = [textView markedTextRange];
    UITextPosition *position = [textView positionFromPosition:markedTextRange.start offset:0];
//高亮状态跳过
    if (position) {
        return;
    }
    NSData *data = [toBeString dataUsingEncoding:NSUTF8StringEncoding];
    if (data.length > maxLengh) {
//判断最后剩一个字符是中文还是英文
         NSData *  lastData = [data subdataWithRange:NSMakeRange(maxLengh, 2)];
         NSString *str1 = [[NSString alloc] initWithData:lastData encoding:stringEncoding];
        if ([str1 isChinese]) {
            data = [data subdataWithRange:NSMakeRange(0, maxLengh-1)];
        }else{
            data = [data subdataWithRange:NSMakeRange(0, maxLengh)];
        }
        NSString *str = [[NSString alloc] initWithData:data encoding:stringEncoding];
        textField.text = str;
        AlertShow(message);
    }
}
- (BOOL)isChinese
{
    NSString *match = @"(^[\u4e00-\u9fa5]+$)";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF matches %@", match];
    return [predicate evaluateWithObject:self];
}


关于输入截取后会清空输入的文本 做了如下调整

    if ([toBeString lengthForChineseAndEnglish] > maxLengh) {
        NSData *  lastData =  [data subdataWithRange:NSMakeRange(maxLengh-3, 2)];
        NSString *str1 = [[NSString alloc] initWithData:lastData encoding:stringEncoding];

        NSData *  lastData3 =  [data subdataWithRange:NSMakeRange(maxLengh-2, 2)];
        NSString *str3 = [[NSString alloc] initWithData:lastData3 encoding:stringEncoding];
        
        NSData *  lastData2 =  [data subdataWithRange:NSMakeRange(maxLengh-1, 2)];
        NSString *str2 = [[NSString alloc] initWithData:lastData2 encoding:stringEncoding];

        NSData *  lastData4 =  [data subdataWithRange:NSMakeRange(maxLengh-4, 2)];
        NSString *str4 = [[NSString alloc] initWithData:lastData4 encoding:stringEncoding];
        
        
        if (([str1 isChinese]&&![str3 isChinese] && [str2 isChinese]) ||(![str1 isChinese]&&![str3 isChinese] && [str2 isChinese]) || ([str1 isChinese]&[str3 isChinese] && [str2 isChinese]&&![str4 isChinese])) {
           data = [data subdataWithRange:NSMakeRange(0, maxLengh-1)];;
        }else{
            data = [data subdataWithRange:NSMakeRange(0, maxLengh)];
        }
        
        NSString *str = [[NSString alloc] initWithData:data encoding:stringEncoding];
        textView.text = str;
        AlertShow(message);
    }

判断暂时这样 有点冗余,后期维护下 看看有什么好的判断解决,欢迎大家提意见
完美解决了,不管是粘贴,还是输入中英文数字混合都完美的截取了。
perfect。

你可能感兴趣的:(iOS UITextField 输入限制字符,并截取限制位置的字符)