zoukankan      html  css  js  c++  java
  • UITextView 限制输入字数

    尊重原创  http://blog.csdn.net/fengsh998/article/details/45421107

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

    1. - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range  
    2.  replacementText:(NSString *)text;//有输入时触但对于中文键盘出示的联想字选择时不会触发  
    3.   
    4. - (void)textViewDidChange:(UITextView *)textView;//当输入且上面的代码返回YES时触发。或当选择键盘上的联想字时触发。  

    第一个用于限制输入,第二个用于动态计算剩余字数。好吧,就来慢慢的给大家分析这两个代理共同协作来限制输入。

    从最简单的开始。为了便于讲析,声明

    #define MAX_LIMIT_NUMS     100 来限制最大输入只能100个字符

     

    完整代码

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

    回顾一下,文章到此,共解决了哪些易遗留的BUG

    1.中,英文字符输入时限制。

    2.带emoji时截取显示半个或乱码字符处理。

  • 相关阅读:
    让UILabel的文字顶部对齐
    常用的iOS开发或者优化的小工具
    AppStoreID--安装URL--应用更新URL--应用评分URL
    iOS 下载功能:断点下载(暂停和开始)(NSURLConnectionDataDelegate方法)
    iOS QLPreviewController(Quick Look)快速浏览jpg,PDF,world等
    如何不让UITableView滚动
    解析字典包含关键字比如ID,description等,MJExtension 框架 不能直接设置变量与其同名。
    今天犯了个小错误:_dataArray.count>1 和_dataArray.count>0搞混淆了
    获取当前的日期和时间-数码
    C/C++中的段错误(Segmentation fault)[转]
  • 原文地址:https://www.cnblogs.com/wangyang1213/p/5885946.html
Copyright © 2011-2022 走看看