zoukankan      html  css  js  c++  java
  • 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表情符都能正常限制和处理,写到这里基本上能解决输入字符的限制。希望对大家有所帮助,谢谢。过程中还有想不到的或未预见的也希望大家留言给我。我好研究再进行补充。欢迎回馈!

  • 相关阅读:
    李开复给学习计算机的学生的7点建议(转)
    linux 命令
    易中天的十句话
    11个笑话让你领悟人生
    心情不好的时候看看
    高校青年老师挣扎在辞职边缘 微薄工资继续啃老
    【33.00%】【vijos P1002】过河
    【33.33%】【codeforces 681D】Gifts by the List
    【19.05%】【codeforces 680D】Bear and Tower of Cubes
    【12.78%】【codeforces 677D】Vanya and Treasure
  • 原文地址:https://www.cnblogs.com/hauler/p/6257013.html
Copyright © 2011-2022 走看看