LXTextField封装

虽说在以前的项目中也有对文本框进行过封装,感觉简化了不少,但是最近一个项目让我非常头疼,先说说产品需求。

  • 需求大致如下:
    输入字符长度限制判定,错误提示
    每单个输入字符合法性校验,错误提示
    输入完成后校验,错误提示
    格式错误与长度,错误提示
    输入字符中间插入空格, 比如 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容