也不是我自己写的 找来的 方便以后使用(MAX_LIMIT_NUMS
宏定义字符串的最大长度,lbNums显示字符串总长度和当前字符串长度的lable)
-
(void)textViewDidChange:(UITextView
*)textView
{
CGSize size =
[textView
sizeThatFits:CGSizeMake(220,
MAXFLOAT)];
CGRect frame
= textView.frame;
frame.size.height =
size.height;
textView.frame = frame;
CGRect
lableFrame = lbNums.frame;
lableFrame.origin.y =
frame.origin.y +
frame.size.height + 2;
lbNums.frame = lableFrame;
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)
{
//截取到最大位置的字符(由于超出截部分在should时被处理了所在这里这了提高效率不再判断)
NSString *s = [nsTextContent
substringToIndex:MAX_LIMIT_NUMS];
[textView setText:s];
}
//不让显示负数
lbNums.text = [NSString
stringWithFormat:@"%ld/%d",MAX(0,MAX_LIMIT_NUMS
- existTextNum),MAX_LIMIT_NUMS];
}
- (BOOL)textView:(UITextView
*)textView shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text
{
if ([text
isEqualToString:@"\n"]) {
[_textViewresignFirstResponder];
return NO;
}else{
UITextRange *selectedRange =
[textView markedTextRange];
//获取高亮部分
UITextPosition *pos = [textView
positionFromPosition:selectedRange.start
offset:0];
//如果有高亮且当前字数开始位置小于最大限制时允许输入
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 =
@"";
//判断是否只普通的字符或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.textstringByReplacingCharactersInRange:range
withString:s]];
//既然是超出部分截取了,哪一定是最大限制了。
lbNums.text = [NSString
stringWithFormat:@"%d/%ld",0,(long)MAX_LIMIT_NUMS];
}
return NO;
}
}
}