TextFiled限制字符串長度問題

在第三方鍵盤加入之后,對于字數(shù)限制的處理不再像之前那么簡單了

純數(shù)字、字符輸入(不包括粘貼)這樣的字數(shù)限制還是相對比較簡單的,你可以用兩種方法進行處理

第一種是textfield的delegate實現(xiàn):

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

if (range.length + range.location > textField.text.length) {

return NO;

}

NSUInteger newLength = textField.text.length + string.length - range.length;

return newLength<=kMaxCharacterCount;

}

第二種是注冊一個通知,在textfield編輯時做處理:

首先你在viewDidLoad中注冊通知

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFiledEditChanged:) name:UITextFieldTextDidChangeNotification object:self.shopName];

再實現(xiàn)通知里面的方法,在超過最大值時,取最大的字數(shù)

if (self.shopName.text.length > kMaxCharacterCount) {

self.shopName.text = [self.shopName.text substringToIndex:kMaxCharacterCount];

}

但是,在中文的限制上面情況就復(fù)雜了,當(dāng)時在調(diào)試的時候,因為使用的是第三方鍵盤,所以當(dāng)時沒有發(fā)現(xiàn)問題,但是在使用系統(tǒng)鍵盤的時候,一下子就蛋疼了….

下面我開始分析一下,兩者的區(qū)別:1、第三方鍵盤在輸入字符時,一般是不會將字符直接輸入到textfield中,而是將字符顯示在它自己的view上方,但是系統(tǒng)鍵盤會直接輸入到textfield中,而且它會占2個字符長度,比如你輸入”abcd”,在textfield中顯示的是”a b c d”,并且”a b c d”是處在高亮中的,并不算是真正輸入到textfield中,所以我們不應(yīng)把高亮的字符計算在內(nèi),我們應(yīng)該計算真正輸入的字符

2、如果我們使用的是delegate做處理的時候,系統(tǒng)中文輸入的時候會有聯(lián)想,但是聯(lián)想的那個字并不會調(diào)用delegate,比如你輸入一個”你”,在系統(tǒng)的聯(lián)想里面可能會出現(xiàn)”的”,”們”這樣的聯(lián)想,但是你選擇”的”的時候,delegate并不會調(diào)用,(尼瑪….),我猜想聯(lián)想輸入應(yīng)該不算做keyboard所觸發(fā)的事件,所以他并不會觸發(fā)delegate,但是如果你注冊的是通知,他倒是會調(diào)用,(還好有救)

另外提醒一下,有時候在自測輸入的時候,要考慮全面,比如粘貼這也是一種輸入,當(dāng)時沒考慮,我也是跪了

好了,分析了主要的區(qū)別下面我們就來看看具體怎么實現(xiàn)吧~

在實現(xiàn)注冊通知方法里面:

#pragma mark - UITextViewDelegate

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

if (textView.text.length == 0) {

self.recommendTips.hidden = NO;

}else{

self.recommendTips.hidden = YES;

}

NSString *toBeString = textView.text;

NSString *lang = self.textInputMode.primaryLanguage; // 鍵盤輸入模式

if ([lang isEqualToString:@"zh-Hans"]) { // 簡體中文輸入,包括簡體拼音,健體五筆,簡體手寫

UITextRange *selectedRange = [textView markedTextRange];

//獲取高亮部分

UITextPosition *position = [textView positionFromPosition:selectedRange.start offset:0];

// 沒有高亮選擇的字,則對已輸入的文字進行字數(shù)統(tǒng)計和限制

if (!position || !selectedRange) {

if (toBeString.length > 200) {

textView.text = [toBeString substringToIndex:200];

}

}

// 有高亮選擇的字符串,則暫不對文字進行統(tǒng)計和限制

else{

}

}

// 中文輸入法以外的直接對其統(tǒng)計限制即可,不考慮其他語種情況

else{

if (toBeString.length > 200) {

textView.text = [toBeString substringToIndex:200];

}

}

}

首先,我們根據(jù)鍵盤的輸入模式進行區(qū)分,英文的比較簡單就和上面一樣,直接取最大的字符數(shù)就好了,在中文輸入的時候,我們用markedTextRange方法獲取到當(dāng)前的光標位置,再用textField positionFromPosition:selectedRange.start offset:0獲取到高亮部分,然后判斷是否有高亮,這個時候系統(tǒng)會調(diào)用兩次通知方法,第一次是將高亮的字符輸入,第二次是將高亮的字符轉(zhuǎn)換成中文輸入(這個時候就沒有高亮了,然后再取最大的字符數(shù)),但是在iOS7的設(shè)備上測試時發(fā)現(xiàn),position都不會為nil,在iOS8以上都正常,但是獲取到光標的range,卻是正常的

NS_CLASS_AVAILABLE_IOS(3_2) @interface UITextRange : NSObject

@property (nonatomic, readonly, getter=isEmpty) BOOL empty;? ? //? Whether the range is zero-length.

@property (nonatomic, readonly) UITextPosition *start;

@property (nonatomic, readonly) UITextPosition *end;

@end

我們可以看到系統(tǒng)的UITextRange,有兩個變量,一個是start,一個是end,這正是對于的高亮區(qū)域!

所以既然position不能使用,那我們干脆就使用range,通過判斷range的存在,來對文字進行限制處理。(粘貼也適用)

結(jié)果也是棒棒的!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容