一個(gè)小需求,對輸入的字?jǐn)?shù)進(jìn)行限制,超過15個(gè)字后不能輸入。其實(shí)包括表情、中文聯(lián)想詞。
- 系統(tǒng)表情占2個(gè)字符,如果最后剩一個(gè)字符后,如果不做限制表情會展示不全。所以如果剩一個(gè)字符就不能輸入。
- 中文聯(lián)想,在高亮的時(shí)候輸入不計(jì)算字符。
網(wǎng)上可以找到很多textView字?jǐn)?shù)限制的寫法,textField比較少,所以在這做一下記錄。
- textfield添加通知 UITextFieldTextDidChangeNotification,用戶在輸入的時(shí)候可以進(jìn)行字?jǐn)?shù)限制和表情、聯(lián)想詞相關(guān)的操作。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChangeExt:) name:UITextFieldTextDidChangeNotification object:nil];
以下是字?jǐn)?shù)限制的實(shí)現(xiàn)方法
- (void)textDidChangeExt:(NSNotification *)notification {
UITextRange *selectedRange = [self.textView markedTextRange];
// 獲取高亮部分 中文聯(lián)想
UITextPosition *posi = [self.textView positionFromPosition:selectedRange.start offset:0];
// 如果在變化中是高亮部分在變,就不要計(jì)算字符
if (selectedRange && posi) {
return;
}
// 實(shí)際總長度
NSInteger realLength = self.textView.text.length;
UITextPosition *beginning = self.textView.beginningOfDocument;
UITextRange *selectRange = self.textView.selectedTextRange;
UITextPosition *selectionStart = selectRange.start;
// 獲取光標(biāo)的位置
NSInteger location = [self.textView offsetFromPosition:beginning toPosition:selectionStart];
// 獲取光標(biāo)后的文本
NSString *tailText = [self.textView.text substringFromIndex:location];
// 光標(biāo)前允許輸入的最大數(shù)量
NSInteger restLength = kCWordsMaxLength - tailText.length;
if (realLength > kCWordsMaxLength) {
// 解決半個(gè)emoji 定位到index位置時(shí),返回在此位置的完整字符的range
NSRange range = [self.textView.text rangeOfComposedCharacterSequenceAtIndex:restLength];
NSString *subHeadText = @"";
// 防止字符串截取越界導(dǎo)致的閃退
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;
// 解決粘貼過多之后,撤銷粘貼 崩潰問題 —— 不會出現(xiàn)彈框
[self.textView.undoManager removeAllActions];
}
}