業(yè)務(wù)需求:
輸入手機(jī)號,當(dāng)輸入到11位時自動結(jié)束第一響應(yīng)收起鍵盤
ps:只看最終結(jié)果的同學(xué)請直接到底部看改進(jìn)方案2。
思路:
在textField的代理方法里有
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
在該方法里判斷textField的長度[1],長度>11時,結(jié)束第一響應(yīng)。代碼如下:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if (range.length + range.location + string.length >= 11) {
[self.textField resignFirstResponder];
[self.view resignFirstResponder];
return NO;
}
return YES;
}
效果1:

效果圖一
分析
可以看到當(dāng)輸入第11位時,鍵盤確實收起,達(dá)到了業(yè)務(wù)需求,但是textField的文本內(nèi)容還是10位。
原因是該方法在系統(tǒng)封裝好的替換字符串方法之前,而此時結(jié)束第一響應(yīng),再替換時,第一響應(yīng)者已經(jīng)不存在了,所以丟棄了替換方法。因此只需在其中手動加入替換自字符串方法即可。
改進(jìn)方案1
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if (range.length + range.location + string.length >= 11) {
if (range.length + range.location + string.length == 11) {
NSMutableString *str = [NSMutableString stringWithString:self.textField.text];
[str insertString:string atIndex:range.location];
self.textField.text = str;
}
[self.textField resignFirstResponder];
[self.view resignFirstResponder];
return NO;
}
return YES;
}
效果2:

效果圖二
分析
可以看到輸入的問題解決了,但是產(chǎn)生了新的問題:當(dāng)刪除時直接取消了第一響應(yīng)并且字符串未改變。
改進(jìn)方案2
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if (![string isEqualToString:@""]) {
if (range.length + range.location + string.length >= 11) {
if (range.length + range.location + string.length == 11) {
NSMutableString *str = [NSMutableString stringWithString:self.textField.text];
[str insertString:string atIndex:range.location];
self.textField.text = str;
}
[self.textField resignFirstResponder];
[self.view resignFirstResponder];
return NO;
}
}
return YES;
}
效果3:

效果圖三
總結(jié)
這里只提供了使用代理方法的實現(xiàn)方式,其他還有KVO等方式也可實現(xiàn)本功能。
補(bǔ)充:
在 iOS10.0 中新增了一個代理方法
- (void)textFieldDidEndEditing:(UITextField *)textField reason:(UITextFieldDidEndEditingReason)reason NS_AVAILABLE_IOS(10_0); // if implemented, called in place of textFieldDidEndEditing:
typedef NS_ENUM(NSInteger, UITextFieldDidEndEditingReason) {
UITextFieldDidEndEditingReasonCommitted,
UITextFieldDidEndEditingReasonCancelled UIKIT_AVAILABLE_TVOS_ONLY(10_0)
} NS_ENUM_AVAILABLE_IOS(10_0);
-
由于該方法是在將要改變時調(diào)用,所以 textField 的長度并不能成為最終判斷條件,這里使用 range.length + range.location + string.length 來計算最終長度 ?