runtime方式添加属性

runtime方式为UITextField控件添加placeholderColor(占位文字颜色)属性。

步骤:

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

UITextField分类:
.h文件
#import 

@interface UITextField (Placeholder)

// 设置占位文字颜色
@property UIColor *placeholderColor;

@end

.m文件
#import "UITextField+Placeholder.h"
#import 

@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方式添加属性)