如何更好地限制一個UITextField的輸入長度
阿新 • • 發佈:2019-02-20
要限制一個UITextField的輸入字數(參考連結),首先想到的應該是通過
UITextFieldDelegate
的代理方法來限制:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; // return NO to not change text
比如要設定字數限制為20:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == self.titleField) {
if (textField.length > 20) return NO;
}
return YES;
}
但是這樣的限制簡單粗暴,可能會影響使用者正常邏輯下的輸入,比如輸入了20個字元後,要退格回刪字元。
這時候我們可能會考慮“Detect backspace in UITextField”,比如簡單地判斷replacementString的長度是否為0。
接著我們可能還會遇到使用者已經輸入20個字元了,這時候繼續輸入---不過是選擇了部分文字進行替換-----無法進行了,這也妨礙了使用者的正常操作,所以限制的程式碼版本可能會演進為:
#pragma mark - UITextFieldDelegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == self.titleField) {
if (string.length == 0) return YES;
NSInteger existedLength = textField.text.length;
NSInteger selectedLength = range.length;
NSInteger replaceLength = string.length;
if (existedLength - selectedLength + replaceLength > 20) {
return NO;
}
}
return YES;
}
到這裡可能會覺得基本大功告成了,但是當你輸入19個字元後,第20個字元以中文漢字的形式繼續輸入,那麼系統會在鍵盤上方提供後續的一系列聯想詞,你會發現通過這種方式可以連續選字輸入從而突破20個字元的限制。WTF
到了這裡,我們可能會希望有個類似
- (void)textFieldDidChange:(UITextField *)textField
的回撥方法,但可惜沒有。
當然,我們還可以通過
- (void)textFieldDidEndEditing:(UITextField *)textField;
回撥方法在結束編輯的時候把文字截斷,雖然在使用者體驗上會有點突兀。
不過當我們點進去UITextField.h標頭檔案裡尋覓上述回撥方法而不得時,可能會發現最下面有這麼個訊息通知名稱:
UIKIT_EXTERN NSString *const UITextFieldTextDidChangeNotification;
不過,監聽訊息還要記得解除監聽,通常我還習慣把監聽訊息的程式碼統一放在一個方法中,看起來有點“大動干戈”。
所幸的是UITextField本身提供了相應的事件監聽:
[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
這樣就可以更好地限制輸入長度:
- (void)textFieldDidChange:(UITextField *)textField
{
if (textField == self.titleField) {
if (textField.text.length > 20) {
textField.text = [textField.text substringToIndex:20];
}
}
}