iOS runtime之動態(tài)關(guān)聯(lián)屬性

提出問題:
ios項(xiàng)目經(jīng)常遇到很多不同要求的textField, 比如這個(gè)要求只能輸入數(shù)字, 那個(gè)要求只能輸入英文字母....如果對每個(gè)textField實(shí)現(xiàn)delegate來判斷,代碼量過大. 有沒有簡化的方法?

方法步驟:
1.給UITextField新增一個(gè)屬性fieldType, 用于區(qū)別textField的輸入類型,就是通過Category, 新增一個(gè)動態(tài)關(guān)聯(lián)屬性(只能生成此屬性的set和get方法,不可生成對應(yīng)的成員變量_fieldType);
2.在APPdelegate中, 程序啟動時(shí), 給UITextField注冊兩個(gè)系統(tǒng)通知;
3.利用正則表達(dá)式, 限制輸入的字符(這里以"只能輸入數(shù)字"為例).



代碼實(shí)現(xiàn)

@interface UITextField (FieldType)
//增加一個(gè)文本類型的屬性(本質(zhì)是僅僅添加了set/get方法,不會增加成員變量)
@property (nonatomic,copy) NSString *fieldType;
@end



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

@implementation UITextField (FieldType)
static const void *tagKey = &tagKey;//自定義的關(guān)聯(lián)標(biāo)識

//set方法
-(void)setFieldType:(NSString *)fieldType{
  
    //給UITextField新增一個(gè)"fieldType"的關(guān)聯(lián)屬性
    //(1)給誰新增方法; (2)關(guān)聯(lián)的唯一標(biāo)識; (3)屬性名; (4)關(guān)聯(lián)策略,如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{
    //根據(jù)'關(guān)聯(lián)標(biāo)識', 返回關(guān)聯(lián)屬性
   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;
}


//第一個(gè)通知來得到我們開始編輯的TextField的原始值
-(void)beginEditingAction:(NSNotification *)notify{
   
    UITextField *textField = (UITextField *)notify.object;
    
    _textStr = textField.text;
    
}
//第二個(gè)通知來判斷我們輸入的字符串符不符合要求,我們首先需要一個(gè)通過正則表達(dá)式判斷是否符合規(guī)范的方法
-(void)infoAction:(NSNotification *)notify{
    
    UITextField *textField = (UITextField *)notify.object ;
    
    /*
     _textStr為我們輸入字符串之前的TextField的值     
     **/
    
    NSString *headStr = _textStr;    
    /**     
     判斷用戶是否進(jìn)行了刪除操作,如果進(jìn)行了刪除操作則該方法return    
     **/
    
    if (textField.text.length < _textStr.length) {
        
        _textStr = textField.text;
        
        return;        
    }
    
    /**     
     得到鍵入的字符串     
     **/    
    NSString *footStr = [textField.text substringFromIndex:_textStr.length];
    
    /**     
     判斷該textField需要滿足校驗(yàn)  
     **/
    
    if ([textField.fieldType isEqualToString:@"number"]) {
        
        NSLog(@"此輸入框我們需要校驗(yàn)的類型!");
        if ([self validateAccount:footStr]) {            
            /**             
   當(dāng)輸入的字符串符合規(guī)范時(shí)把新輸入的字符串添加到輸入框顯示的字符串中             
             **/            
            _textStr = [NSString stringWithFormat:@"%@%@",headStr,footStr];
            
        }else{
            
            /*
             不符合規(guī)范時(shí)輸入框的內(nèi)容依然為我們輸入字符串之前的值 
             **/
            textField.text = headStr;  
        }
        
    }else {
        
        NSLog(@"此輸入框不是我們想要的類型,不需要校驗(yàn)");
    }
}

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

<br>   
   動態(tài)關(guān)聯(lián)屬性, 指的是為某個(gè)類新增一個(gè)"關(guān)聯(lián)屬性", 與屬性的區(qū)別是不會生成一個(gè)_屬性名的成員變量. 所以,Category只能新增方法.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容