UITextView--字数限制

(1)自带输入法中,由于中文输入的特殊性,会在使用拼音时用字母和空格占位,需要忽略中文正在拼写,需要注意的是,很多第三方输入法在输入中文时都是拼写完才添加到输入框中。
(2)对于含有emoji的字符串,会占多个长度,可以通过NSStringEnumerationByComposedCharacterSequences的遍历方式来得到字符串的字符个数。

汉语拼音时不计入字数统计,兼顾iOS 8+,以及对emoji的统计处理,一下为具体代码:

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

UITextRange* selectedRange = [textView markedTextRange];
UITextPosition* position = [textView positionFromPosition:selectedRange.start offset:0];
if (selectedRange&&position) {//同样先判断是否处于中文输入拼音的情况,如果是,则不做任何处理,包括不变化显示字的总个数。
    
    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 < MaxTextCount) {
        return YES;
    }else{
        return NO;
    }
}
NSString* comcatstr = [textView.text stringByReplacingCharactersInRange:range withString:text];
NSInteger caninputLength = MaxTextCount - comcatstr.emoji_lengthWith;
if (caninputLength >= 0) {
    
    return YES;
}else{
    NSInteger len = text.emoji_lengthWith +caninputLength;
    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;
}  

return YES;
}

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

UITextRange*selectedRange = [textView markedTextRange];//获取高亮部分
UITextPosition* position = [textView positionFromPosition:selectedRange.start offset:0];
if (selectedRange&&position) {//同样先判断是否处于中文输入拼音的情况,如果是,则不做任何处理,包括不变化显示字的总个数。
    return;
}
NSString*textContent = textView.text;
NSInteger existTextNum = textContent.emoji_lengthWith;
if (existTextNum>MaxTextCount) {
    //截取最大位置的字符
    NSString*s = [textContent substringToIndex:MaxTextCount];
    [textView setText:s];
}

}


//对含有emoji表情的字符串做处理
-(NSInteger)emoji_lengthWith{

__block NSInteger length = 0;
[self enumerateSubstringsInRange:NSMakeRange(0, self.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
    length++;
}];
return length;;

}

如果服务端数据库并不支持emoji表情,可以将其转码为NSNonLossyASCIIStringEncoding形式的字符串,展示时再转回NSUTF8StringEncoding。
如下所示:

NSString* dog = @"🐶";
NSData* data = [dog dataUsingEncoding:NSNonLossyASCIIStringEncoding];
NSString* dogStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"dogstr:%@",dogStr);

NSData* data1 = [dogStr dataUsingEncoding:NSUTF8StringEncoding];
   NSString* dogStr1 = [[NSString alloc]initWithData:data1 encoding:NSNonLossyASCIIStringEncoding];
   NSLog(@"dogStr1:%@",dogStr1);