层次一:利用富文本

   // 描述占位文字属性
NSMutableDictionary *dict = [NSMutableDictionary dictionary] ;
dict[NSForegroundColorAttributeName] = [UIColor whiteColor]; // 富文本字符串
NSAttributedString *arrtString = [[NSAttributedString alloc] initWithString:self.placeholder attributes:dict];
self.attributedPlaceholder = arrtString;

此种方式需要书写的代码较多,过于麻烦

方法二:利用KVC

  • 通过Debug View Hierarchy(通常所说的小面包)工具查看UITextField的图层和控件发现,UITextField内部有一个UITextFieldLabel,猜测它就是用来做占位图片的控件。

  • 通过断点调试查看UITextField的内部属性名,通过属性名获得内部私有属性placeholderLabel,然后改变颜色即可

  • 代码

UILabel *placeholderLabel = [self valueForKey:@"placeholderLabel"];
placeholderLabel.textColor = [UIColor whiteColor];

此种方式代码简单不少,但是我们更希望通过点语法设置对象属性的方式那样去设置,下面看第三种方法

层次三:利用runtime

  • 思路:为UITextField增加一个分类,通过runtime的方式为UITextField增加placeholderColor属性

UITextField+placeholderColor.h 文件

@interface UITextField (placeholderColor)

@property (nonatomic, strong) UIColor *placeholderColor;

@end

UITextField+placeholderColor.m 文件

#import "UITextField+placeholderColor.h"
#import <objc/message.h> @implementation UITextField (placeholderColor) // placeholderColor的set方法
- (void)setPlaceholderColor:(UIColor *)placeholderColor { // 给UITextField添加placeholderColor属性,并设置其值为placeholderColor
// object:保存到哪个对象中
// key:属性名
// value:属性值
// policy:策略
objc_setAssociatedObject(self, @"placeholderColor", placeholderColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC); // 利用KVC方式 改变系统UITextField的占位文字的颜色
UILabel *placeholderLabel = [self valueForKey:@"placeholderLabel"];
placeholderLabel.textColor = placeholderColor;
} // placeholderColor的get方法
- (UIColor *)placeholderColor { // 获取属性的值
return objc_getAssociatedObject(self, @"placeholderColor");
} @end

这样我们就可以在工程中包含这个分类,利用点语法的方式设置占位文字的颜色,非常方便,但是在使用中会有一个bug

//  使用方式1
self.textField.placeholder = @"jimg";
self.textField.placeholderColor = [UIColor redColor]; // 使用方式2
self.textField.placeholderColor = [UIColor redColor];
self.textField.placeholder = @"jimg";

使用方式1设置可以将占位文字设置为红色,但是方式2就没有任何效果, 原因分析:

  • 原因是系统自带控件的子控件都是懒加载的,方式2情况下在设置placeholder后placeholder的label才会加载,只有在此之后设置placeholderColor才会有效。

解决办法:

  • 在设置placeholderColor的颜色时将颜色保存一份,当设置placeholder时再设置一遍placeholderColor,系统的设置placeholder方法并没有这样的功能,这时就要用到runtime将系统设置placeholder的方法换成我们自己写的方法,而且这种交换只需要执行一次,所以在类的load方法中操作。

完善后的UITextField+placeholderColor.m 文件

#import "UITextField+placeholderColor.h"
#import <objc/message.h> static UIColor *_placeholderColor; @implementation UITextField (placeholderColor) // placeholderColor的set方法
- (void)setPlaceholderColor:(UIColor *)placeholderColor { // 给UITextField添加placeholderColor属性,并设置其值为placeholderColor
// object:保存到哪个对象中
// key:属性名
// value:属性值
// policy:策略
objc_setAssociatedObject(self, @"placeholderColor", placeholderColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC); UILabel *placeholderLabel = [self valueForKey:@"placeholderLabel"];
placeholderLabel.textColor = placeholderColor; // 保存placeholderColor
_placeholderColor = placeholderColor;
} // placeholderColor的get方法
- (UIColor *)placeholderColor { // 获取属性的值
return objc_getAssociatedObject(self, @"placeholderColor");
} // 将类加载到内存时调用
+(void)load { [super load];
// 获取系统的setPlaceholder
Method setPlaceholderMethod = class_getClassMethod(self, @selector(setPlaceholder:));
// 获取自定义的setPlaceholder
Method ymf_setPlaceholderMethod = class_getClassMethod(self, @selector(ymf_setPlaceholder:)); // 交换方法
method_exchangeImplementations(setPlaceholderMethod, ymf_setPlaceholderMethod);
} // 自定义的setPlaceholder方法
- (void)ymf_setPlaceholder:(NSString *) placeholde {
// 完成系统的操作,注意此时系统的setPlaceholder方法已经换成了ymf_setPlaceholder
[self ymf_setPlaceholder:placeholde]; // 再设置一边placeholderColor
[self placeholderColor];
} @end

至此,就可以不再关系设置顺序的问题正确设置UITextField占位文字的颜色了。

最新文章

  1. [UML]UML系列——活动图activity diagram
  2. 添加IP安全策略 远离系统Ping漏洞的威胁
  3. oracle vm virtualbox右ctrl切换显示模式
  4. VS2015——命令行下编译、静态库动态库制作以及断点调试
  5. HtmlPrefixScopeExtensions
  6. jQuery MVC 科室异步联动
  7. 已经不再更新新浪、网易及CSDN博客了!
  8. Go 解析JSON
  9. 2014第2周四部署环境&amp;买火车票
  10. 如何一秒钟从头构建一个 ASP.NET Core 中间件
  11. 01基于配置文件方式的SpringMVC,三种HandlerMapping,三种控制器
  12. 第12章 添加对外部认证的支持 - Identity Server 4 中文文档(v1.0.0)
  13. java 随机生成6位短信验证码
  14. input type=date时,时间数据回填,报错The specified value &quot;2019-0404-18&quot; does not conform to the required format, &quot;yyyy-MM-dd&quot;.
  15. 【十三】jvm 性能调优工具之 jstack
  16. Linux 4.20内核得到更新,英特尔CPU 性能降低50%
  17. 12-关于DOM操作的相关案例
  18. Spring Security 认证流程
  19. 弹框alertView
  20. 静态工厂方法和实例工厂方法及普通的bean

热门文章

  1. hadoop+海量数据面试题汇总(二)
  2. ymodem协议c实现(转)
  3. .htaccess 使用大全
  4. ios 计算字符串长度&lt;转&gt;
  5. X-004 FriendlyARM tiny4412 uboot移植之点亮指路灯
  6. IOS开发根据字体大小等获取文字所占的高度
  7. begin lydsy 2731
  8. java中常用的空判断
  9. Spark中的wordCount程序实现
  10. js函数对象