对于车牌号的输入限制来说,算是相对于来说比较麻烦的,不像手机号限制,只需要进行键盘限制和输入的时候进行数字校验就可以。而车牌号也是有相对应格式的:汉字+大写字母+大写字母或数字(5位)。
我们通常在进行校验的时候,一般都在这个方法中进行校验:
- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string
但是我们在进行首字母为汉字的时候就会出现问题,因为我们在输入汉字的时候,键盘会将我们输入的拼音进行高亮展示放在textfield中(例如:我们想要输入“京”,textfield会将拼音jing展示出来包含在蓝色区域内),无法获取我们想要的汉字进行校验。导致我们无法在这个方法中进行输入校验。
那么我们就换一种方式处理,对textfield进行输入监听
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldTextHasChange:) name:UITextFieldTextDidChangeNotification object:self.textField];
监听事件处理
- (void)textFieldTextHasChange:(NSNotification *)notification {
//获取高亮部分
UITextRange *selectedRange = self.textField.markedTextRange;
UITextPosition *position = [self.textField positionFromPosition:selectedRange.start offset:0];
if (!position) { // 没有高亮选择的字
if ([self.applyModel.name containsString:@"车牌号"]) {
// 在输入的时候校验车牌号
if (![ProveModel inputValidateWithTextField:self.textField]) {
return;
}
}
}else { //有高亮文字
//do nothing
}
}
下边是用到的一些判断方法和限制方法,我将他们单独写在一个校验类里,方便其他地方调用。
#pragma mark - 车牌号输入限制
+ (BOOL)inputValidateWithTextField:(UITextField *)textField {
NSString *strNew = [NSString stringWithString:textField.text];
if (strNew.length > 7) { // 7位
strNew = [strNew substringToIndex:7];
}
for (int i = 1; i<=strNew.length; i++) {
if (i == 1) {
NSString *firstStr = [strNew substringToIndex:1];
if ([firstStr isChinese]) { // 判断是否为汉字
[textField setText:firstStr];
} else {
// 设置为空串,不然会将第一个输入的非汉字记录在textfield中
textField.text = @"";
return NO;
}
}
if (i == 2) {
NSString *secondStr = [strNew substringWithRange:NSMakeRange(1, 1)];
if ([self isUpperEnglish:secondStr]) { // 判断是否为大写字母
[textField setText:[strNew substringToIndex:i]];
} else {
// 这里不需要再设置 self.textField的值,因为再i==1的时候设置过啦(for循环)。
return NO;
}
}
if (i > 2) {
NSString *str = [strNew substringWithRange:NSMakeRange(i-1, 1)];
if ([self numAndUpperEnglish:str]) { // 判断是否为大写字母和数字
[textField setText:[strNew substringToIndex:i]];
} else {
return NO;
}
}
}
return YES;
}
#pragma mark - 判断是否是汉字
- (BOOL)isChinese
{
NSString *chinese = @"^[\u4E00-\u9FA5]*$";
NSPredicate *chinesePredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", chinese];
return [chinesePredicate evaluateWithObject:self];
}
#pragma mark - 判断是否是大写字母
#define UPPER @"ABCDEFGHIJKLMNOPQRSTUVWXYZ" // 大写字母
+ (BOOL)isUpperEnglish:(NSString *)str
{
for (int i= 0; i
#pragma mark - 判断是否是大写字母和数字
#define UPPERNUM @"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" // 大写字母和数字
+ (BOOL)numAndUpperEnglish:(NSString *)str
{
for (int i= 0; i
这样就可以实现对车牌号进行输入的时候进行逐个校验。方法虽然有点low但是是可以实现功能的。
最后附加一个输入完成后的车牌号正则校验方法。
#pragma mark ***_车牌号正则_***
- (BOOL)validateCarNo:(NSString*)carNo {
NSString *carRegex =@"^[\u4e00-\u9fa5]{1}[a-zA-Z]{1}[a-zA-Z_0-9]{4}[a-zA-Z_0-9_\u4e00-\u9fa5]$";
NSPredicate *carTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",carRegex];
// NSLog(@"carTest is %@",carTest);
if ([carTest evaluateWithObject:carNo]) {
return YES;
}else{
return NO;
}
}