iOS runtime之动态关联属性

提出问题:
ios项目经常遇到很多不同要求的textField, 比如这个要求只能输入数字, 那个要求只能输入英文字母....如果对每个textField实现delegate来判断,代码量过大. 有没有简化的方法?

方法步骤:
1.给UITextField新增一个属性fieldType, 用于区别textField的输入类型,就是通过Category, 新增一个动态关联属性(只能生成此属性的set和get方法,不可生成对应的成员变量_fieldType);
2.在APPdelegate中, 程序启动时, 给UITextField注册两个系统通知;
3.利用正则表达式, 限制输入的字符(这里以"只能输入数字"为例).



代码实现

@interface UITextField (FieldType)
//增加一个文本类型的属性(本质是仅仅添加了set/get方法,不会增加成员变量)
@property (nonatomic,copy) NSString *fieldType;
@end



#import "UITextField+FieldType.h"
#import <objc/runtime.h>

@implementation UITextField (FieldType)
static const void *tagKey = &tagKey;//自定义的关联标识

//set方法
-(void)setFieldType:(NSString *)fieldType{
  
    //给UITextField新增一个"fieldType"的关联属性
    //(1)给谁新增方法; (2)关联的唯一标识; (3)属性名; (4)关联策略,如retain,copy等.
    objc_setAssociatedObject(self, tagKey, fieldType, OBJC_ASSOCIATION_COPY_NONATOMIC);
    
    // @param object The source object for the association.
    // @param key The key for the association.
    // @param value The value to associate with the key key for object. Pass nil to clear an existing association.
    // @param policy The policy for the association.
}

//get方法
-(NSString *)fieldType{
    //根据'关联标识', 返回关联属性
   return objc_getAssociatedObject(self, tagKey);
}



@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    //程序一启动, 就立马注册通知.
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(beginEditingAction:) name:UITextFieldTextDidBeginEditingNotification object:nil];   
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(infoAction:) name:UITextFieldTextDidChangeNotification object:nil];
    return YES;
}


//第一个通知来得到我们开始编辑的TextField的原始值
-(void)beginEditingAction:(NSNotification *)notify{
   
    UITextField *textField = (UITextField *)notify.object;
    
    _textStr = textField.text;
    
}
//第二个通知来判断我们输入的字符串符不符合要求,我们首先需要一个通过正则表达式判断是否符合规范的方法
-(void)infoAction:(NSNotification *)notify{
    
    UITextField *textField = (UITextField *)notify.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.fieldType isEqualToString:@"number"]) {
        
        NSLog(@"此输入框我们需要校验的类型!");
        if ([self validateAccount:footStr]) {            
            /**             
   当输入的字符串符合规范时把新输入的字符串添加到输入框显示的字符串中             
             **/            
            _textStr = [NSString stringWithFormat:@"%@%@",headStr,footStr];
            
        }else{
            
            /*
             不符合规范时输入框的内容依然为我们输入字符串之前的值 
             **/
            textField.text = headStr;  
        }
        
    }else {
        
        NSLog(@"此输入框不是我们想要的类型,不需要校验");
    }
}

- (BOOL)validateAccount:(NSString *)textString{
    
    NSString *number = @"^[0-9xX]+$";    
    NSPredicate *numberPre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",number];   
    return [numberPre evaluateWithObject:textString];
    
}

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

推荐阅读更多精彩内容