UITextView 输入字数限制

本文介绍了UITextView对中英文还有iOS自带表情输入的字数限制,由于中文输入会有联想导致字数限制不准确所以苦恼好久,所以参考一些大神的博客终于搞定,欢迎大家参考和指正。

 对于限制UITextView输入的字符数。相信大家在网上见得最多的是实现UITextViewDelegate

    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range  
     replacementText:(NSString *)text;
      
    - (void)textViewDidChange:(UITextView *)textView;

第一个限制输入,有输入时会调用,但是中文下会有问题:中文联想选字时不会调用;

第二个用于动态计算剩余字数,当输入且第一个方法返回YES时触发。或当选择键盘上的联想字时触发。

不多说,直接上代码

1 #define MAX_LIMIT_NUMS 100 //最大限制字数
 1 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
 2     UITextRange *selectedRange = [textView markedTextRange];
 3     //获取高亮部分
 4     UITextPosition *pos = [textView positionFromPosition:selectedRange.start offset:0];
 5     //获取高亮部分内容
 6     //NSString * selectedtext = [textView textInRange:selectedRange];
 7     
 8     //如果有高亮且当前字数开始位置小于最大限制时允许输入
 9     if (selectedRange && pos) {
10         NSInteger startOffset = [textView offsetFromPosition:textView.beginningOfDocument toPosition:selectedRange.start];
11         NSInteger endOffset = [textView offsetFromPosition:textView.beginningOfDocument toPosition:selectedRange.end];
12         NSRange offsetRange = NSMakeRange(startOffset, endOffset - startOffset);
13         
14         if (offsetRange.location < MAX_LIMIT_NUMS) {
15             return YES;
16         }
17         else
18         {
19             return NO;
20         }
21     }
22     
23     NSString *comcatstr = [textView.text stringByReplacingCharactersInRange:range withString:text];
24     
25     NSInteger caninputlen = MAX_LIMIT_NUMS - comcatstr.length;
26     
27     if (caninputlen >= 0)
28     {
29         return YES;
30     }
31     else
32     {
33         NSInteger len = text.length + caninputlen;
34         //防止当text.length + caninputlen < 0时,使得rg.length为一个非法最大正数出错
35         NSRange rg = {0,MAX(len,0)};
36         
37         if (rg.length > 0)
38         {
39             NSString *s = @"";
40             //判断是否只普通的字符或asc码(对于中文和表情返回NO)
41             BOOL asc = [text canBeConvertedToEncoding:NSASCIIStringEncoding];
42             if (asc) {
43                 s = [text substringWithRange:rg];//因为是ascii码直接取就可以了不会错
44             }
45             else
46             {
47                 __block NSInteger idx = 0;
48                 __block NSString  *trimString = @"";//截取出的字串
49                 //使用字符串遍历,这个方法能准确知道每个emoji是占一个unicode还是两个
50                 [text enumerateSubstringsInRange:NSMakeRange(0, [text length])
51                                          options:NSStringEnumerationByComposedCharacterSequences
52                                       usingBlock: ^(NSString* substring, NSRange substringRange, NSRange enclosingRange, BOOL* stop) {
53                                           
54                                           if (idx >= rg.length) {
55                                               *stop = YES; //取出所需要就break,提高效率
56                                               return ;
57                                           }
58                                           
59                                           trimString = [trimString stringByAppendingString:substring];
60                                           
61                                           idx++;
62                                       }];
63                 
64                 s = trimString;
65             }
66             //rang是指从当前光标处进行替换处理(注意如果执行此句后面返回的是YES会触发didchange事件)
67             [textView setText:[textView.text stringByReplacingCharactersInRange:range withString:s]];
69         }
70         return NO;
71     }
72 }
 1 -(void)textViewDidChange:(UITextView *)textView
 2 {
 3     UITextRange *selectedRange = [textView markedTextRange];
 4     //获取高亮部分
 5     UITextPosition *pos = [textView positionFromPosition:selectedRange.start offset:0];
 6     //如果在变化中是高亮部分在变,就不要计算字符了
 7     if (selectedRange && pos) {
 8         return;
 9     }
10     NSString  *nsTextContent = textView.text;
11     NSInteger existTextNum = nsTextContent.length;
12     
13     if (existTextNum > MAX_LIMIT_NUMS)
14     {
15         //截取到最大位置的字符(由于超出截部分在should时被处理了所在这里这了提高效率不再判断)
16         NSString *s = [nsTextContent substringToIndex:MAX_LIMIT_NUMS];
17         
18         [textView setText:s];
19     }22 }

上述的代码,在输入中,英文,emoji表情符都能正常限制和处理,写到这里基本上能解决输入字符的限制。希望对大家有所帮助,谢谢。过程中还有想不到的或未预见的也希望大家留言给我。我好研究再进行补充。欢迎回馈!

原文地址:https://www.cnblogs.com/hauler/p/6257013.html