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:中再次设置,以后写代码必须先设置"占位文字",再设置"占位文字颜色"。
疑惑:自定义方法的用处?
- 通过交换方法给系统方法添加代码,是添加代码的桥梁。
网友评论