runtime方式添加属性

作者: 闲得一B | 来源:发表于2016-03-15 06:55 被阅读130次
    runtime方式为UITextField控件添加placeholderColor(占位文字颜色)属性。

    步骤:

    1、创建UITextField分类,添加属性。
    2、导包<objc/message.h> 。
    3、自定义设置 "占位文字" 私有方法。
    4、runtime获取系统类"设置占位文字" 方法、获取自定义方法。
    5、runtime交换获取到的两个方法。
    6、将添加的属性与系统的类关联
    7、KVC获取到系统类的 "占位文字"。
    8、设置 "占位文字颜色" 。
    9、自定义方法中 "再次" 设置 "占位文字颜色"。

    UITextField分类:
    .h文件
    #import <UIKit/UIKit.h>
    
    @interface UITextField (Placeholder)
    
    // 设置占位文字颜色
    @property UIColor *placeholderColor;
    
    @end
    
    
    .m文件
    #import "UITextField+Placeholder.h"
    #import <objc/message.h>
    
    @implementation UITextField (Placeholder)
    
    + (void)load
    {
         Method setPlaceholderMethod = class_getInstanceMethod(self, @selector(setPlaceholder:));
         Method xdyb_setPlaceholderMethod = class_getInstanceMethod(self, @selector(xdyb_setPlaceholder:));
        
         // 交互方法 
         method_exchangeImplementations(setPlaceholderMethod, xdyb_setPlaceholderMethod);
        
    }
    
    // 设置占位文字颜色
    - (void)setPlaceholderColor:(UIColor *)placeholderColor
    {
        // 方法作用: 保存占位文字颜色到系统的类,并且关联
        // 参数:
        // object:保存到哪个对象中
        // key:属性名
        // value:属性值
        // policy:策略
        objc_setAssociatedObject(self, @"placeholderColor", placeholderColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
        //KVC获取系统类的占位文字属性
        UILabel *placeholderLabel = [self valueForKeyPath:@"placeholderLabel"];
        //设置占位文字颜色
        placeholderLabel.textColor = placeholderColor;
    }
    
    //获取颜色
    - (UIColor *)placeholderColor
    {
        return objc_getAssociatedObject(self, @"placeholderColor");
    }
    
    //自定义设置占位文字颜色方法
    - (void)xdyb_setPlaceholder:(NSString *)placeholder
    {
        // 设置占位文字,不会造成死循环
        [self xdyb_setPlaceholder:placeholder];
        
        // 设置占位文字颜色,再次设置是为了保证以后代码无序
        self.placeholderColor = self.placeholderColor;
    }
    
    @end
    
    用法:
    导入分类,直接设置placeholderColor
    
    方法:

    valueForKeyPath:-- KVC方式获取属性
    class_getInstanceMethod() -- 获取对象属性
    method_exchangeImplementations() -- 交换方法
    objc_getAssociatedObject -- 获取关联系统属性的值
    objc_setAssociatedObject -- 保存占位文字到系统的类,并关联

    疑惑:交换方法?
    • 将系统方法和自定义方法交换。
    • 调用系统方法就会来调用自定义方法。
    • 调用自定义方法就会来调用系统的方法。
    • 当调用系统方法时,来到自定义方法中,此时自定义方法中调用自己,其实调用自己就是调用系统方法。
    疑惑:两次设置占位文字颜色?
    • 为了保证设置 "占位文字颜色" 和设置 “占位文字” 的代码"无序"。
    • 如果不在自定义方法xdyb_setPlaceholder:中再次设置,以后写代码必须先设置"占位文字",再设置"占位文字颜色"。
    疑惑:自定义方法的用处?
    • 通过交换方法给系统方法添加代码,是添加代码的桥梁。

    相关文章

      网友评论

        本文标题:runtime方式添加属性

        本文链接:https://www.haomeiwen.com/subject/gtaflttx.html