zoukankan      html  css  js  c++  java
  • iOS开发中UITextView使用小结

      最近项目开发中用到了多行文本框限制文字输入个数限制,之前的话在textViewDidChange方法中截取超出字数就可以。测试人员发现在拼音转汉字的过程中,YYTextView不会二次确认textViewDidChange方法,输入字数只能最后确认结束弹框的时候计算,影响体验效果,后转用自己封装的继承UITextView替换。另外拼音转汉字的情况下,在输入文本中间一直输入,依然会出现输入字数计算不准确的问题。下面列出解决问题实现的代码。

      

    #pragma mark- UITextViewDelegate

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

    {

        [self.activityTextView resignFirstResponder];

    }

     

    -(void)updateSpeechButtonStatus{

        if (self.activityTextView.text.length >= MAX_NUM) {

            self.btnSpeech.enabled = NO;

        }else{

            self.btnSpeech.enabled = YES;

        }

    }

    //动态显示可输入文本字数

    -(void)changeTextNumber:(UITextView *)textView{

        if (textView.text.length <= MAX_NUM) {

            self.numLabel.text = [NSString stringWithFormat:@"%lu/%lu",(unsigned long)textView.text.length,(MAX_NUM - textView.text.length)];

        }else{

            self.numLabel.text = [NSString stringWithFormat:@"%@/%@",[NSString stringWithFormat:@"%d",MAX_NUM],@"0"];

        }

    }

    -(void)textViewDidChange:(UITextView *)textView{

        

        UITextRange *selectedRange = [textView markedTextRange];

        //获取高亮部分

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

        

        //如果是拼音转汉语状态不统计字数,确认输入后统计

        if (selectedRange && pos) {

            return;

        }

        

        [self changeTextNumber:textView];

        [self updateSpeechButtonStatus];

        

    }

    -(void)textViewDidEndEditing:(UITextView *)textView{

        textView.text = [EaseEmoji stringReplaceEmoji:textView.text];

        [self changeTextNumber:textView];

        [self updateSpeechButtonStatus];

    }

     

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

    {

        BOOL isLimit = [CCCommonAPI textViewTextCountLimit:textView range:range text:text maxCount:[NSString stringWithFormat:@"%d",MAX_NUM] isAllowEmoji:YES completeBlock:^{

            //执行这里block的时候不执行textViewDidChange,block里面的内容就是textViewDidChange里面的操作

            [self changeTextNumber:textView];

            [self updateSpeechButtonStatus];

        }];

        return isLimit;

        

    }

    //textview字数限制处理

    + (BOOL)textViewTextCountLimit:(UITextView *)textView range:(NSRange)range text:(NSString *)text maxCount:(NSString *)maxCountStr isAllowEmoji:(BOOL)isAllowEmoji completeBlock:(nonnull CommonTextLimitCompletion)completeBlock{

        

        if (!isAllowEmoji) {

            //不允许输入表情的时候返回NO

            if ([[[UITextInputMode currentInputMode] primaryLanguage] isEqualToString:@"emoji"]) {

                return NO;

            }

        }

        

        //对于退格删除键开放限制

        if (text.length == 0) {return YES;}

            

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

        

        NSInteger caninputlen = [maxCountStr intValue] - 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 = @"";

                //判断是否只普通的字符或asc码(对于中文和表情返回NO)

                BOOL asc = [text canBeConvertedToEncoding:NSASCIIStringEncoding];

                if (asc) {

                    s = [text substringWithRange:rg];//因为是ascii码直接取就可以了不会错

                }else{

                    __block NSInteger idx = 0;

                    __block NSString  *trimString = @"";//截取出的字串

                    //使用字符串遍历,这个方法能准确知道每个emoji是占一个unicode还是两个

                    [text enumerateSubstringsInRange:NSMakeRange(0, [text length])

                                                  options:NSStringEnumerationByComposedCharacterSequences

                                               usingBlock: ^(NSString* substring, NSRange substringRange, NSRange enclosingRange, BOOL* stop) {

                                                   

                                                   if (idx >= rg.length) {

                                                       *stop = YES; //取出所需要就break,提高效率

                                                       return ;

                                                   }

                                                   

                                                   trimString = [trimString stringByAppendingString:substring];

                                                   

                                                   idx++;

                                               }];

                    

                    s = trimString;

                }

                //rang是指从当前光标处进行替换处理(注意如果执行此句后面返回的是YES会触发didchange事件)

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

                

                completeBlock();

                

                //手动截取更改,不再调用didchange

                return NO;

            }else{

                UITextRange *selectedRange = [textView markedTextRange];

                //获取高亮部分

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

                

                if (selectedRange && pos) {

                    //如果拼音转汉语状态继续输入

                    return YES;

                }else{

                    return NO;

                }

            }

        }

    }

  • 相关阅读:
    MVC ORM 架构
    Kubernetes 第八章 Pod 控制器
    Kubernetes 第七章 Configure Liveness and Readiness Probes
    Kubernetes 第六章 pod 资源对象
    Kubernetes 第五章 YAML
    Kubernetes 核心组件
    Kubernetes 架构原理
    Kubernetes 第四章 kubectl
    Kubernetes 第三章 kubeadm
    yum 配置及yum 源配置
  • 原文地址:https://www.cnblogs.com/bigant9527/p/15155578.html
Copyright © 2011-2022 走看看