美文网首页
iOS开发中UITextView使用小结

iOS开发中UITextView使用小结

作者: 奔跑的小蚂蚁_8b28 | 来源:发表于2021-10-09 08:48 被阅读0次

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

image

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;
    
          }
    
      }
    

    }

}

相关文章

网友评论

      本文标题:iOS开发中UITextView使用小结

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