美文网首页
限制字数的textview

限制字数的textview

作者: 牛小牛啊 | 来源:发表于2018-04-16 15:08 被阅读0次

    好久没有写文章了,今天上来写写,发现增多了markDown编辑器。挺不错,后续研究一下,今天暂写文章先。好了,不废话。

    如题,相信大家看到这个标题都不想看文章了,这有什么好说的,网上一搜一大把。好吧,自认为是一搜一大把的跳过,有兴趣的就看完。。。。。。

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

    [objc] view plain copy

    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range  

     replacementText:(NSString *)text;//有输入时触但对于中文键盘出示的联想字选择时不会触发  

    - (void)textViewDidChange:(UITextView *)textView;//当输入且上面的代码返回YES时触发。或当选择键盘上的联想字时触发。  

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

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

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

    详细的实现代码:

    [objc] view plain copy

    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range  

     replacementText:(NSString *)text  

    {  

    NSString *comcatstr = [textView.text stringByReplacingCharactersInRange:range withString:text];  

    NSInteger caninputlen = MAX_LIMIT_NUMS - comcatstr.length;  

    if (caninputlen >= 0)  

        {  

    return YES;  

        }  

    else  

        {  

    NSInteger len = text.length + caninputlen;  

    //防止当text.length + caninputlen < 0时,使得rg.length为一个非法最大正数出错  

    NSRange rg = {0,MAX(len,0)};  

    if (rg.length > 0)  

            {  

    NSString *s = [text substringWithRange:rg];  

    [textView setText:[textView.text stringByReplacingCharactersInRange:range withString:s]];  

            }  

    return NO;  

        }  

    }  

    - (void)textViewDidChange:(UITextView *)textView  

    {  

    NSString  *nsTextContent = textView.text;  

    NSInteger existTextNum = nsTextContent.length;  

    if (existTextNum > MAX_LIMIT_NUMS)  

        {  

    //截取到最大位置的字符  

    NSString *s = [nsTextContent substringToIndex:MAX_LIMIT_NUMS];  

    [textView setText:s];  

        }  

    //不让显示负数  

    self.lbNums.text = [NSString stringWithFormat:@"%ld/%d",MAX(0,MAX_LIMIT_NUMS - existTextNum),MAX_LIMIT_NUMS];  

    }  

    最终运行效果:

    图片这么大?^_^。大家看到这是不是就表示OK了呢。就提交代码了呢?

    好,下面就对上面的简单代进行逐一BUG找出且进行修复。

    1.遗留BUG(只考虑了英文键盘下处理)

      上述代码在英文键盘下基本上是可以正常,但如果是在中文(生在天朝啊必须得懂中文)或9宫格键盘下会有什么问是呢。下图是我截图,当输入到只剩下一个字时,这时输入拼音时,问题出现了,发现拼音输不完。另一个问题是当离字数上限差距很大时,输入拼音会发现字数也跟着计算了。本来还没有输入的,此时开始计算了,有瘕次。

    如图,在最后一个,本想输入一个拼音h开头的且还没有出现在推荐字的。哪再输入第二位拼音时发现不能输了,且字数被计算了。

    对上述可能有朋友说,这算什么BUG。基本上没怎么碰到这情况。嗯确实,但如果是在一段字中间插入的时候呢。这个是有可能出现的。

    哪么怎么样处理这样的产生的BUG呢。从分析来看事实上输入拼音还处于高亮状态,哪么有没有什么办法来获取呢。于是呼搜寻中。。。。。。

    Ok,确实有这样的好。加上后代码如下:

    [objc] view plain copy

    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range  

     replacementText:(NSString *)text  

    {  

    UITextRange *selectedRange = [textView markedTextRange];  

    //获取高亮部分  

    UITextPosition *pos = [textView positionFromPosition:selectedRange.start offset:0];  

    //获取高亮部分内容  

    //NSString * selectedtext = [textView textInRange:selectedRange];  

    //如果有高亮且当前字数开始位置小于最大限制时允许输入  

    if (selectedRange && pos) {  

    NSInteger startOffset = [textView offsetFromPosition:textView.beginningOfDocument toPosition:selectedRange.start];  

    NSInteger endOffset = [textView offsetFromPosition:textView.beginningOfDocument toPosition:selectedRange.end];  

            NSRange offsetRange = NSMakeRange(startOffset, endOffset - startOffset);  

    if (offsetRange.location < MAX_LIMIT_NUMS) {  

    return YES;  

            }  

    else  

            {  

    return NO;  

            }  

        }  

    NSString *comcatstr = [textView.text stringByReplacingCharactersInRange:range withString:text];  

    NSInteger caninputlen = MAX_LIMIT_NUMS - comcatstr.length;  

    if (caninputlen >= 0)  

        {  

    return YES;  

        }  

    else  

        {  

    NSInteger len = text.length + caninputlen;  

    //防止当text.length + caninputlen < 0时,使得rg.length为一个非法最大正数出错  

    NSRange rg = {0,MAX(len,0)};  

    if (rg.length > 0)  

            {  

    NSString *s = [text substringWithRange:rg];  

    [textView setText:[textView.text stringByReplacingCharactersInRange:range withString:s]];  

    //既然是超出部分截取了,哪一定是最大限制了。  

    self.lbNums.text = [NSString stringWithFormat:@"%d/%ld",0,(long)MAX_LIMIT_NUMS];  

            }  

    return NO;  

        }  

    }  

    - (void)textViewDidChange:(UITextView *)textView  

    {  

    UITextRange *selectedRange = [textView markedTextRange];  

    //获取高亮部分  

    UITextPosition *pos = [textView positionFromPosition:selectedRange.start offset:0];  

    //如果在变化中是高亮部分在变,就不要计算字符了  

    if (selectedRange && pos) {  

    return;  

        }  

    NSString  *nsTextContent = textView.text;  

    NSInteger existTextNum = nsTextContent.length;  

    if (existTextNum > MAX_LIMIT_NUMS)  

        {  

    //截取到最大位置的字符  

    NSString *s = [nsTextContent substringToIndex:MAX_LIMIT_NUMS];  

    [textView setText:s];  

        }  

    //不让显示负数 口口日  

    self.lbNums.text = [NSString stringWithFormat:@"%ld/%d",MAX(0,MAX_LIMIT_NUMS - existTextNum),MAX_LIMIT_NUMS];  

    }  

    相关文章

      网友评论

          本文标题:限制字数的textview

          本文链接:https://www.haomeiwen.com/subject/vxrekftx.html