效果展示:
默认.png
白色.png
红色.png
实现效果:
1、placeholder 的颜色根据要求变换
2、textField 光标颜色也根据需求变换
UITextField 默认只能设置placeholder内容,而不能设置其内容属性;为了达到上述要求需要做到两点:
1、找到 UITextField 隐藏属性(私有成员变量)
2、访问/设置 UITextField 隐藏属性(私有成员变量)
为了实现上述第一个需求,我们需要使用Runtime来查找其私有成员变量:
1、首先导入runtime.h(自定义类,继承自UITextField)
#import <objc/runtime.h>
2、通过runtime机制,查询UITextField的私有成员变量
unsigned int outCount = 0;
// copy出UITextField的所有成员变量名称
// 参数一:需要知道哪个类的私有成员,就传入哪个类
// 参数二:一个统计类私有成员的变量(传地址)
Ivar *ivars = class_copyIvarList([UITextField class], &outCount);
for (NSInteger i = 0; i < outCount; ++i) {
// 遍历取出该类成员变量
/*
// 方式一
Ivar *ivar = (ivars + i);
NSLog(@"%s", ivar_getName(*ivar));
*/
/*
// 方式二
Ivar ivar = *(ivars + i);
NSLog(@"%s", ivar_getName(ivar));
*/
/*
// 方式三
Ivar ivar = ivars[i];
NSLog(@"%s", ivar_getName(ivar));
*/
}
// 根据内存管理原则释放指针
free(ivars);
通过上述遍历,得到一系列输出:
placeholder.png
上图中的 _placeholder 就是本次遍历的目标。
通过KVC设置私有属性的值
// 当textField成为第一响应者的时候,更改其文字颜色、内容以及光标颜色
- (BOOL)becomeFirstResponder{
self.placeholder = @"我是第一响应者";
self.tintColor = _placeholdColor;
[self setValue:_placeholdColor forKeyPath:@"_placeholderLabel.textColor"];
return [super becomeFirstResponder];
}
// 当textField取消成为第一响应者的时候,还原其文字颜色、内容以及光标颜色
- (BOOL)resignFirstResponder{
self.placeholder = self.placehold;
[self setValue:self.textColor forKeyPath:@"_placeholderLabel.textColor"];
return [super resignFirstResponder];
}
总结
不仅仅是对 UITextField 有效;在开发过程中,如果遇到这种类似“变态”的需求,结合runtime和KVC是一个很好的思路。
最后,感谢MJ
网友评论