TextFiled限制字符串長度問題

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

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

第一種是textfield的delegate實現:

- (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];

再實現通知里面的方法,在超過最大值時,取最大的字數

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

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

}

但是,在中文的限制上面情況就復雜了,當時在調試的時候,因為使用的是第三方鍵盤,所以當時沒有發現問題,但是在使用系統鍵盤的時候,一下子就蛋疼了….

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

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

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

好了,分析了主要的區別下面我們就來看看具體怎么實現吧~

在實現注冊通知方法里面:

#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];

// 沒有高亮選擇的字,則對已輸入的文字進行字數統計和限制

if (!position || !selectedRange) {

if (toBeString.length > 200) {

textView.text = [toBeString substringToIndex:200];

}

}

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

else{

}

}

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

else{

if (toBeString.length > 200) {

textView.text = [toBeString substringToIndex:200];

}

}

}

首先,我們根據鍵盤的輸入模式進行區分,英文的比較簡單就和上面一樣,直接取最大的字符數就好了,在中文輸入的時候,我們用markedTextRange方法獲取到當前的光標位置,再用textField positionFromPosition:selectedRange.start offset:0獲取到高亮部分,然后判斷是否有高亮,這個時候系統會調用兩次通知方法,第一次是將高亮的字符輸入,第二次是將高亮的字符轉換成中文輸入(這個時候就沒有高亮了,然后再取最大的字符數),但是在iOS7的設備上測試時發現,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

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

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

結果也是棒棒的!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容