雖說在以前的項目中也有對文本框進行過封裝,感覺簡化了不少,但是最近一個項目讓我非常頭疼,先說說產品需求。
- 需求大致如下:
輸入字符長度限制判定,錯誤提示
每單個輸入字符合法性校驗,錯誤提示
輸入完成后校驗,錯誤提示
格式錯誤與長度,錯誤提示
輸入字符中間插入空格, 比如 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