虽说在以前的项目中也有对文本框进行过封装,感觉简化了不少,但是最近一个项目让我非常头疼,先说说产品需求。
- 需求大致如下:
输入字符长度限制判定,错误提示
每单个输入字符合法性校验,错误提示
输入完成后校验,错误提示
格式错误与长度,错误提示
输入字符中间插入空格, 比如 199 9994 3333, ¥1,000,000.00
文本框returntype设定
文本框非空判定与按钮冻结状态绑定
文本框指定位数发送信息到服务器
发送请求时替换文本框分割符
左视图,右视图,图片内容设置
图片文字设定
图片占位文字设定
......若干天过去了......
XXX改一下,瞬间整个人都崩溃了。
莫要让无意义的事情一直重复下去....
- 根据以上需求,可想而知,单纯的对某个校验方法,和文本框数据处理方法封装后依然有很大Loading,毕竟项目中大本分均为数据采集,每次修改工作量巨大。
- 解决方案: 为了减少后续维护的loading,决定对原来的代码再次进行重构。
- 首先对项目中常用的十种类型的文本框枚举列了出来
- 将所有的校验方式,提示信息,和文本的默认配置信息,提取出来放入一个单独的配置文件,以后需求的修改全部对配置文件进行修改
- 将文本框的 开始编辑,编辑中,结束编辑,编辑完成全部进行重写,并通过block回调方式提供外部定义的接口。
- 为了方便后续对文本框进行扩展,对相关样式和校验方式提供属性以便修改。
- 针对多个文本框验证条件管理事件,设置block绑定事件, 将多个文本框关联子在一起,并按照顺序设定其returnKeyType类型
- 最终于效果:
经过上述优化后,项目中文框代码量减少了80%以上,基本上只需要一次for循环,一次绑定,全部搞定。
LXTextField介绍:
- 基本使用用法如下:
根据文本框类型初始化并创建,通常只需要一个for循环就能全部搞定了
CGFloat orignY = 100;
CGFloat centerX = self.view.bounds.size.width*0.5;
NSMutableArray* allTextFields = [NSMutableArray array];
NSMutableArray* moblieAndPwdTFs = [NSMutableArray array];
LXTextField* tempTF;
for (int index = 0;index < 10 ; index++) {
tempTF = [LXTextField textFieldType:index right:nil left:nil];
tempTF.center = CGPointMake(centerX, orignY);
orignY+= 50;
[self.view addSubview:tempTF];
[allTextFields addObject:tempTF];
if (index == LXTextFieldType_moblie ||
index == LXTextFieldType_pwd ) {
[moblieAndPwdTFs addObject:tempTF];
}
}
[self setupBtnsCenterX:centerX orignY:orignY];
//case1: 判断指定文本非空后btn显示为可点击,同时自动添加文本returnKeyType
[LXTextField blindTextFields:allTextFields editChange:^(BOOL isEnable) {
nextStepBtn.enabled = isEnable;
}];
//case2: 自动所有指定的文本正则验证OK后 btn切换为可点击状态
[LXTextField blindTextFields:allTextFields condition:LXTextCondition_verfiyOK complement:^(BOOL isSuccess) {
nextStepBtn.enabled = isSuccess;
}];
//case3: 指定需要验证的文本框,和需要验证类型(如非空,字符格式校验),并实时回调验证的结果
[LXTextField blindTextFields:moblieAndPwdTFs condition:LXTextCondition_verfiyOK complement:^(BOOL isSuccess) {
if (isSuccess && phoneCodeBtn.enabled == NO) {
phoneCodeBtn.enabled = YES;
}
}];
//case4: 对单个文本框 开始,正在,结束,退出 编辑,进行统一的回调处理
LXTextField* mobileTF = [LXTextField textFieldType:LXTextFieldType_moblie right:nil left:nil];
mobileTF.center = CGPointMake(self.view.center.x, self.view.bounds.size.height - 25);
[self.view addSubview:mobileTF];
[[[[[mobileTF textFieldBeginEdit:^(LXTextField *textField) {
NSLog(@"textFieldBeginEdit:%@",textField.text);
}] textFieldChangeCharacter:^(LXTextField *textField, BOOL sucess) {
NSLog(@"textFieldChangeCharacter:%@",textField.text);
}] textFieldEditChange:^(LXTextField *textField) {
NSLog(@"textFieldEditChange:%@",textField.text);
}] textFieldEditEnd:^(LXTextField *textField) {
NSLog(@"textFieldEditEnd:%@",textField.text);
}] textFieldDidEndOnExit:^(LXTextField *textField) {
NSLog(@"textFieldEditChange:%@",textField.text);
}];
//case5: 对文本框的校验为空进行取消
mobileTF.checkEnable = NO;
mobileTF.AllowEmptyForBtnClick = NO;
mobileTF.rightView = [UIView new];
//case6: 替换某个文本的校验方式
mobileTF.regx = @"^1[3|4|5|7|8]\\d{8}$";
mobileTF.regexChar = @"[0~9]";
mobileTF.maxLength = 11; //注意设置最大长度范围不能超过regx匹配的最大范围。
//case7: 自定义设置某个文本中间的空白位置
mobileTF.seperator = @" ";
mobileTF.seperators = @[@3,@4,@4]; //表示需要将文本截成3,4,4段,中间用空格隔开。
//case8: 错误提示,分别为单个字符输入非法提示, 输入完成校验提示,可以修改配置。
/** - (void)showErrorType:(ErrorType)errorType notice:(NSString*)notice; */
//case9: 针对项目需求可以在 textFieldResuorce.bundle/textFieldConfig.json中的配置文件中进行统一的修改。
配置文件内容:
{
"typeKeys": [
"userName",
"pwd",
"mobile",
"phoneCode",
"imageCode",
"idCardNum",
"bankNum",
"num",
"money",
"url",
"mail"
],
"leftImageName": { //配置默认的图片名
"userName": "userName",
"pwd": "pwd",
"mobile": "mobile",
"phoneCode": "userName",
"imageCode": "userName",
"idCardNum": "idCard",
"bankNum": "bankCard",
"num": "idCard",
"money": "idCard",
"url": "idCard",
"mail": "idCard"
},
"leftTitle": { //配置文本框默认title
"userName": "用户名",
"pwd": "密 码",
"mobile": "手机",
"phoneCode": "手机验证码",
"imageCode": "图形验证码",
"idCardNum": "身份证号",
"bankNum": "银行卡号",
"num": "期数",
"money": "金额",
"url": "网址",
"mail": "邮箱"
},
"placeHolder": { //配置默认占位文字
"userName": "请输入您的姓名",
"pwd": "请输入您的密码",
"mobile": "请输入您的手机号码",
"phoneCode": "请输入短信验证码",
"imageCode": "请输入图形验证码",
"idCardNum": "请输入您的身份证号",
"bankNum": "请输入您的银行卡号",
"num": "请输入您的还款期数",
"money": "请输入金额",
"url": "请输入对应的网址",
"mail": "请输入您的邮箱"
},
"maxLength": { //设定默认的长度
"userName": 12,
"pwd": 20,
"mobile": 11,
"phoneCode": 6,
"imageCode": 6,
"idCardNum": 18,
"bankNum": 19,
"num": 20,
"money": 9,
"url": 200,
"mail": 30
},
"notice": { //设定默认的提示文字
"userName": "请您输入3~10位数字,字母",
"pwd": "请您输入6~20位字母,数字,字符组成的密码",
"mobile": "请您输入11位数的手机号码",
"phoneCode": "验证码格式不正确,请您确认后再次输入",
"imageCode": "验证码格式不正确,请您确认后再次输入",
"idCardNum": "身份证格式不正确,请您核对后再次输入",
"bankNum": "身份证格式不正确,请您核对后再次输入",
"num": "请输入存数字",
"money": "对不起您输入的金额超上限,请重新输入",
"url": "网址格式不正确,请您核对后输入",
"mail": "邮件格式不正确,请您核对后输入"
},
"regx": { //设定默认校验方式
"userName": "^[A-Za-z]{3,40}$",
"pwd": "[a-zA-Z0-9]\\w{6,15}$",
"mobile": "^1[3|4|5|7|8][0-9]{9}$",
"phoneCode": "[0-9]{4,6}",
"imageCode": "[A-Za-z0-9]{1,6}",
"idCardNum": "\\d{14}[[0-9],0-9xX]",
"bankNum": "^\\d{16}|\\d{19}$",
"num": "[0-9]+",
"money": "^[^0][0-9]{0,9}",
"url": "^(http|https)://[^\\s]*$",
"mail": "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
},
"charRegx": { //设定默认的输入字符合法校验方式
"userName": "[a-zA-Z]{1,}",
"pwd": "[a-zA-Z0-9]",
"mobile": "[0-9]",
"phoneCode": "[0-9]",
"imageCode": "[A-Za-z0-9]",
"idCardNum": "[0-9]",
"bankNum": "[0-9]",
"num": "[0-9]",
"money": "[0-9]",
"url": "[0-9a-zA-Z]|[(.)]",
"mail": "[0-9a-zA-Z]|[(.)]|[@]"
},
"seperator": { //设定分割符的样式
"mobile": " ",
"idCardNum": " ",
"bankNum": " ",
},
"seperators": { //设定分割符需要在文本中插入的位置
"mobile": [3,4,4],
"idCardNum": [6,4,4,4],
"bankNum":[4,4,4,4,3]
},
"seperatorRegx": { //设定分割符的校验方式
"mobile": "[^0-9]+",
"idCardNum": "[^0-9]+",
"bankNum": "[^0-9]+",
}
}
github地址:https://github.com/LongXiangGuo/LXTextField/tree/master