在開發(fā)過程中水评,用到textField控件,往往需要用戶輸入手機號銀行卡甲锡。然而產(chǎn)品經(jīng)理最多事兆蕉,非得給你增加難度。手機號必須第三位和第七位后邊加入一個空格或者"-"缤沦。做成形如138-8888-8888的形勢虎韵,同理,銀行卡輸入也必須是6214 8888 8888 8888的形勢缸废。好多人看到可能會說包蓝,這個簡單啊,我有三種方式來解決:1.實現(xiàn)delegate的-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string方法呆奕,2.添加target selector事件的方法养晋,3.KVO的方法衬吆。這樣每次輸入操作都會被監(jiān)聽到梁钾,然后在指定的位后邊添加空格不就行了嗎?然而情況其實并沒有開起來那么簡單逊抡。
一姆泻、問題引入
拿手機號碼格式化來說。設置textField的text在第三位和第八位后添加一個空格冒嫡。這個在順序輸入的時候完全沒有問題拇勃,但是刪除呢?問題來了:1.刪除的時候就需要多刪除一個空格孝凌;2.從中間刪去空格方咆,剩下了非格式化的字符串。對于第一個問題同樣可以檢測刪除的時候把空格刪除蟀架;對于第二個問題瓣赂,可以每次都格式化一下剩余字符串然后重新賦值給textField的text∑模看似完美解決了問題煌集,自測也沒有問題啊。但是也許等到產(chǎn)品上線后才發(fā)現(xiàn)捌省,為什么我修改中間幾位的時候苫纤,光標會直接跳到最后。是的,直接賦值textField的text會讓光標跳轉(zhuǎn)到最后卷拘。這樣的體驗很不好喊废。經(jīng)過一段時間的小研究,小編我研究出了一個解決方案栗弟,特此給大家奇文共賞一下操禀。
二、實現(xiàn)思路
直接上代碼(明眼人可能一下就明白了)
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSLog(@"%@",NSStringFromRange(range));
if (textField) {
NSString* text = textField.text;
//刪除
if([string isEqualToString:@""]){
//刪除一位
if(range.length == 1){
//最后一位,遇到空格則多刪除一次
if (range.location == text.length-1 ) {
if ([text characterAtIndex:text.length-1] == ' ') {
[textField deleteBackward];
}
return YES;
}
//從中間刪除
else{
NSInteger offset = range.location;
if (range.location < text.length && [text characterAtIndex:range.location] == ' ' && [textField.selectedTextRange isEmpty]) {
[textField deleteBackward];
offset --;
}
[textField deleteBackward];
textField.text = [self parseString:textField.text];
UITextPosition *newPos = [textField positionFromPosition:textField.beginningOfDocument offset:offset];
textField.selectedTextRange = [textField textRangeFromPosition:newPos toPosition:newPos];
return NO;
}
}
else if (range.length > 1) {
BOOL isLast = NO;
//如果是從最后一位開始
if(range.location + range.length == textField.text.length ){
isLast = YES;
}
[textField deleteBackward];
textField.text = [self parseString:textField.text];
NSInteger offset = range.location;
if (range.location == 3 || range.location == 8) {
offset ++;
}
if (isLast) {
//光標直接在最后一位了
}else{
UITextPosition *newPos = [textField positionFromPosition:textField.beginningOfDocument offset:offset];
textField.selectedTextRange = [textField textRangeFromPosition:newPos toPosition:newPos];
}
return NO;
}
else{
return YES;
}
}
else if(string.length >0){
//限制輸入字符個數(shù)
if (([self noneSpaseString:textField.text].length + string.length - range.length > 11) ) {
return NO;
}
//判斷是否是純數(shù)字(千殺的搜狗横腿,百度輸入法颓屑,數(shù)字鍵盤居然可以輸入其他字符)
// if(![string isNum]){
// return NO;
// }
[textField insertText:string];
textField.text = [self parseString:textField.text];
NSInteger offset = range.location + string.length;
if (range.location == 3 || range.location == 8) {
offset ++;
}
UITextPosition *newPos = [textField positionFromPosition:textField.beginningOfDocument offset:offset];
textField.selectedTextRange = [textField textRangeFromPosition:newPos toPosition:newPos];
return NO;
}else{
return YES;
}
}
return YES;
}
-(NSString*)noneSpaseString:(NSString*)string
{
return [string stringByReplacingOccurrencesOfString:@" " withString:@""];
}
- (NSString*)parseString:(NSString*)string
{
if (!string) {
return nil;
}
NSMutableString* mStr = [NSMutableString stringWithString:[string stringByReplacingOccurrencesOfString:@" " withString:@""]];
if (mStr.length >3) {
[mStr insertString:@" " atIndex:3];
}if (mStr.length > 8) {
[mStr insertString:@" " atIndex:8];
}
return mStr;
}
效果圖
銀行卡號的格式化也很簡單,只需要重寫
parseString :
每隔4位添加一個空格就好具體代碼在我的github上耿焊。這里還有一個身份證鍵盤的自定義揪惦。