我们在开发的时候经常会碰到这样的问题:一个APP上有很多个TextField存在于不同的页面上,这时候客户或者项目经理要求我们对每一个TextField做不同的检验判断(即其中一个输入框只能输入中文,另外一个输入框只能输入数字或者英文等)。最近本人碰到这样的一个要求,最开始的时候想着用TextField代理的方式来判断,但是这样的话对于APP上存在很多的输入框的项目来说比较繁琐,因为这样的话我们需要在代理中判断当前响应的是哪一个输入框,还要在所有存在输入框的页面上加上代理。那么有没有一种方法更好的方法来解决这样的问题呢。于是我想到在AppDelegate中增加监听来检测APP中存在的所有输入框以实现这一需求。实现逻辑如下:
1、给TextField增加一个属性,我们在页面上add TextField时给这个属性一个值;
2、在AppDelegate中增加监听来检测APP中所有的输入框;
3、监听到当前输入框的动态时来通过正则表达式来判断输入的字符是否符合我们的规范。
以下为关键实现代码:
给TextField增加属性:我采用的是类别(Category)来给TextField增加一个自定义的属性
//在TextField中新建一个textType属性
@property (nonatomic , copy)NSString *textType;
所以就需要在.m中通过runtime来写这个属性的set 和get方法
static const void *tagKey = &tagKey;
@implementation UITextField (TextType)
- (NSString *)textType{
return objc_getAssociatedObject(self, tagKey);
}
- (void)setTextType:(NSString *)textType{
objc_setAssociatedObject(self, tagKey, textType, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
因为用到了runtime,就需要我们导入
#import <objc/runtime.h>
这样给TextField增加一个自定义属性就做好了,接下来要给我们需要校验的TextField的这一属性赋值
inputTextField.textType = @"ACCOUNTNUM";
我们通过在APPDelegate中来监听APP中所有的输入框。在这里我用了两个通知中心来实现
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(beginEditingAction:) name:UITextFieldTextDidBeginEditingNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(infoAction:) name:UITextFieldTextDidChangeNotification object:nil];
第一个通知来得到我们开始编辑的TextField的原始值
- (void)beginEditingAction:(NSNotification *)aNotification{
UITextField *textField = (UITextField *)aNotification.object;
_textStr = textField.text;
}
第二个通知来判断我们输入的字符串符不符合要求,我们首先需要一个通过正则表达式判断是否符合规范的方法
- (BOOL)validateAccount:(NSString *)textString{
NSString *number = @"^[0-9xX]+$";
NSPredicate *numberPre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",number];
return [numberPre evaluateWithObject:textString];
}
然后开始判断
- (void)infoAction:(NSNotification *)aNotification{
UITextField *textField = (UITextField *)aNotification.object ;
/**
_textStr为我们输入字符串之前的TextField的值
**/
NSString *headStr = _textStr;
/**
判断用户是否进行了删除操作,如果进行了删除操作则该方法return
**/
if (textField.text.length < _textStr.length) {
_textStr = textField.text;
return;
}
/**
得到输入的字符串
**/
NSString *footStr = [textField.text substringFromIndex:_textStr.length];
/**
判断该textField需要满足哪一种校验
**/
if ([textField.textType isEqualToString:@"ACCOUNTNUM"]) {
if ([self validateAccount:footStr]) {
/**
当输入的字符串符合规范时把新输入的字符串添加到输入框显示的字符串中
**/
_textStr = [NSString stringWithFormat:@"%@%@",headStr,footStr];
}else{
/**
不符合规范时输入框的内容依然为我们输入字符串之前的值
**/
textField.text = headStr;
}
}else if ([textField.textType isEqualToString:@"NAME"]){
}
else{
NSLog(@"other");
}
}
以上即为我们实现这一功能的全部逻辑及实现代码。
ps:谢谢小章同学的大力支持。本人系iOS小白,还在对于iOS的学习还在摸索中。不喜勿喷,欢迎指正。:)
网友评论