一个小需求,对输入的字数进行限制,超过15个字后不能输入。其实包括表情、中文联想词。
- 系统表情占2个字符,如果最后剩一个字符后,如果不做限制表情会展示不全。所以如果剩一个字符就不能输入。
- 中文联想,在高亮的时候输入不计算字符。
网上可以找到很多textView字数限制的写法,textField比较少,所以在这做一下记录。
- textfield添加通知 UITextFieldTextDidChangeNotification,用户在输入的时候可以进行字数限制和表情、联想词相关的操作。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChangeExt:) name:UITextFieldTextDidChangeNotification object:nil];
以下是字数限制的实现方法
- (void)textDidChangeExt:(NSNotification *)notification {
UITextRange *selectedRange = [self.textView markedTextRange];
// 获取高亮部分 中文联想
UITextPosition *posi = [self.textView positionFromPosition:selectedRange.start offset:0];
// 如果在变化中是高亮部分在变,就不要计算字符
if (selectedRange && posi) {
return;
}
// 实际总长度
NSInteger realLength = self.textView.text.length;
UITextPosition *beginning = self.textView.beginningOfDocument;
UITextRange *selectRange = self.textView.selectedTextRange;
UITextPosition *selectionStart = selectRange.start;
// 获取光标的位置
NSInteger location = [self.textView offsetFromPosition:beginning toPosition:selectionStart];
// 获取光标后的文本
NSString *tailText = [self.textView.text substringFromIndex:location];
// 光标前允许输入的最大数量
NSInteger restLength = kCWordsMaxLength - tailText.length;
if (realLength > kCWordsMaxLength) {
// 解决半个emoji 定位到index位置时,返回在此位置的完整字符的range
NSRange range = [self.textView.text rangeOfComposedCharacterSequenceAtIndex:restLength];
NSString *subHeadText = @"";
// 防止字符串截取越界导致的闪退
if (range.location > self.textView.text.length || range.location < 0) {
subHeadText = [self.textView.text substringToIndex:kCWordsMaxLength];
} else {
subHeadText = [self.textView.text substringToIndex:range.location];
}
self.textView.text = subHeadText;
// 解决粘贴过多之后,撤销粘贴 崩溃问题 —— 不会出现弹框
[self.textView.undoManager removeAllActions];
}
}