在输入框中输入手机号码/电话号码/银行卡号/身份证号时经常需要格式化显示, 用户体验更好.
网上解决方法很多,找了不少但也是不太适合,于是把其中一些修改成以下方法, 在UITextField
的分类中添加过滤,浸入性小,耦合性小,用起来还是很方便的.间隔符号可以自定义,过滤条件也可以自己增加和修改, 如只能输入数字和X(身份证号)等限制.
直接上代码:
UITextField
的分类:
UITextField+Extension.h
#import <UIKit/UIKit.h>
// 准许输入字符类型
typedef NS_ENUM(NSInteger, CharsType) {
CharsType_numeral = 1, // 只许数字
CharsType_letter, // 只许大小写字母
CharsType_numeralAndXx, // 只许数字加上X和x
CharsType_numeralAndLetter, // 只许数字加上大小写字母
CharsType_allChar, // 允许输入所有字符
};
@interface UITextField (Extension)
/**
* 格式化输入的文字
*
* @param textField 正在输入的textField
* @param range 输入字符的位置
* @param string 输入的字符
* @param CharType 准许输入字符类型
* @param maxLength 限制输入文字的最大长度
* @param indexs 插入分隔符的位置下标数组
* @param separator 插入的分隔符号
*
* @return 是否加显示到textField输入框内
*/
+ (BOOL)textField:(UITextField *)textField range:(NSRange)range string:(NSString *)string CharType:(CharsType)CharType maxLength:(NSInteger)maxLength separatorIndexs:(NSArray *)indexs separator:(NSString *)separator;
@end
UITextField+Extension.m
#import "UITextField+Extension.h"
@implementation UITextField (Extension)
+ (BOOL)textField:(UITextField *)textField range:(NSRange)range string:(NSString *)string CharType:(CharsType)CharType maxLength:(NSInteger)maxLength separatorIndexs:(NSArray *)indexs separator:(NSString *)separator {
if ([string isEqualToString:separator]) return NO;
// 添加限制条件,只能输入这个字符串内的字符
NSString *allowChar;
switch (CharType) {
case CharsType_numeral:
allowChar = @"0123456789\b";
break;
case CharsType_letter:
allowChar = @"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM\b";
break;
case CharsType_numeralAndXx:
allowChar = @"0123456789Xx\b";
break;
case CharsType_numeralAndLetter:
allowChar = @"0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM\b";
break;
default:
break;
}
NSCharacterSet *characterSet;
if (CharType != CharsType_allChar) {
characterSet = [NSCharacterSet characterSetWithCharactersInString:allowChar];
string = [string stringByReplacingOccurrencesOfString:separator withString:@""];
if ([string rangeOfCharacterFromSet:[characterSet invertedSet]].location != NSNotFound) {
return NO;
}
}
NSString *text = textField.text;
if ([string isEqualToString:@""]){
if (range.length == 1) {
if (range.location == text.length - 1) {
if ([[text substringFromIndex:text.length -1] isEqualToString:separator]) {
[textField deleteBackward];
}
return YES;
}
else {
NSInteger offset = range.location;
if (range.location < text.length && [[text substringFromIndex:range.location] isEqualToString:separator] && [textField.selectedTextRange isEmpty]) {
[textField deleteBackward];
offset --;
}
[textField deleteBackward];
textField.text = [self parseString:textField.text separatorIndexs:indexs separator:separator];
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 separatorIndexs:indexs separator:separator];
__block NSInteger offset = range.location;
[indexs enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSInteger index = [obj integerValue];
if (range.location == index) 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) {
NSString *str;
if (CharType != CharsType_allChar) {
str = [textField.text stringByTrimmingCharactersInSet:[characterSet invertedSet]];
}
str = [textField.text stringByReplacingOccurrencesOfString:separator withString:@""];
if ((str.length + string.length - range.length > maxLength) ) {
return NO;
}
[textField insertText:string];
textField.text = [self parseString:textField.text separatorIndexs:indexs separator:separator];
__block NSInteger offset = range.location + string.length;
[indexs enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSInteger index = [obj integerValue];
if (range.location == index) offset++;
}];
UITextPosition *newPos = [textField positionFromPosition:textField.beginningOfDocument offset:offset];
textField.selectedTextRange = [textField textRangeFromPosition:newPos toPosition:newPos];
return NO;
} else {
return YES;
}
}
+ (NSString *)parseString:(NSString*)string separatorIndexs:(NSArray *)indexs separator:(NSString *)separator {
if (!string) return nil;
NSMutableString *mStr = [NSMutableString stringWithString:[string stringByReplacingOccurrencesOfString:separator withString:@""]];
[indexs enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSInteger index = [obj integerValue];
if (mStr.length > index) [mStr insertString:separator atIndex:index];
}];
return mStr;
}
@end
使用:
#import "ViewController.h"
#import "UITextField+Extension.h"
@interface ViewController () <UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet UITextField *tf_phone;
@property (weak, nonatomic) IBOutlet UITextField *tf_idCard;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_tf_phone.delegate = self;
_tf_idCard.delegate = self;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField == _tf_phone) {
return [UITextField textField:textField range:range string:string CharType:CharsType_numeral maxLength:11 separatorIndexs:@[@(3), @(8)] separator:@"-"];
} else if (textField == _tf_idCard) {
return [UITextField textField:textField range:range string:string CharType:CharsType_numeralAndXx maxLength:18 separatorIndexs:@[@(6), @(11), @(16)] separator:@" "];
}
return YES;
}
@end