UITextFiled/UITextView--占位文字
案例说明--以UITextFiled为例
- 自定义一个UITextFiled
- 在storyboard中拖入两个TextFiled继承于自定义的UITextFiled
- 在自定义UITextFiled类中对占位文字进行统一设置
一.占位文字--添加
方法一:使用代码添加占位文字
self.placeholder = @"hahaha";
方法二:使用Xcode修改添加占位文字
二.占位文字--修改属性值
方法一:使用UITextFiled的属性:attributedPlaceholder
- 查找技巧:进入头文件(或者继承的父类头文件)中查找
self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:@{NSForegroundColorAttributeName:[UIColor grayColor]}];
※补充知识: 富文本
--带有属性的字符串
富文本用法
用法一:不可变的属性文字
- 使用不可变的属性文字NSAttributedString设置占位文字的背景色
// 富文本用法1 - 不可变的属性文字
self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:@{NSForegroundColorAttributeName:[UIColor grayColor]}];
用法二:可变的属性文字
- 利用可变的属性文字NSMutableAttributedString可以实现设置每个占位文字的颜色/字体不同
//富文本用法2 - 可变的属性文字
NSMutableDictionary *attr = [NSMutableDictionary dictionary];
attr[NSForegroundColorAttributeName] = [UIColor grayColor];
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:self.placeholder];
[string setAttributes:attr range:NSMakeRange(0, 1)];
self.attributedPlaceholder = string;
用法三:图文混排
- 实现功能:利用可变的属性文字,存放拼接的不可变的属性文字
- 利用不可变属性文字存放图片需要在不可变属性文字创建的时候设置一个父控件NSTextAttachment
- 父控件NSTextAttachment有image属性,可以用来存放图片
//1.创建可变属性文字存放不同属性文字
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] init];
//2.创建第1个不可变属性文字
NSAttributedString *str1 = [[NSAttributedString alloc] initWithString:self.placeholder];
//拼接不可变属性文字
[string appendAttributedString:str1];
//3.创建第2个带图片的不可变属性文字
//NSTextAttachment用于存放图片信息的父控件
NSTextAttachment *att = [[NSTextAttachment alloc] init];
att.image = [UIImage imageNamed:@"header_cry_icon"];
NSAttributedString *str2 = [NSAttributedString attributedStringWithAttachment:att];
//图片进行微调
att.bounds = CGRectMake(0, -2, 16, 16);
//拼接不可变属性文字
[string appendAttributedString:str2];
//4.创建第3个不可变属性文字
NSAttributedString *str3 = [[NSAttributedString alloc] initWithString:@"哈哈"];
//拼接不可变属性文字
[string appendAttributedString:str3];
//5.设置UITextFiled显示自定义的占位文字
self.attributedPlaceholder = string;
方法二:使用UITextFiled的方法:drawPlaceholderInRect
- 可以在drawPlaceholderInRect画出占位文字
- 方法1: 使用drawInRect画
- 方法2: 使用drawAtPoint画
- (void)drawPlaceholderInRect:(CGRect)rect
{
//设置文字的属性
NSMutableDictionary *attr = [NSMutableDictionary dictionary];
attr[NSFontAttributeName] = self.font;
attr[NSForegroundColorAttributeName] = [UIColor whiteColor];
//方法一:drawInRect
// //文字所在矩形框
// CGRect placeholderRect = rect;
// placeholderRect.origin.y = (self.height - self.font.lineHeight)/2;
//
// //InRect画占位文字
// [self.placeholder drawInRect:placeholderRect withAttributes:attr];
//方法二:drawAtPoint
//文字所在坐标
CGPoint point;
point.x = 0;
point.y = (self.height - self.font.lineHeight)/2;
//AtPoint画占位文字
[self.placeholder drawAtPoint:point withAttributes:attr];
}
方法三:使用UITextFiled的私有成员变量placeholderLabel
- 根据开发经验可以猜出,UITextFiled的占位文字可能是由一个UILabel来控制的
- 使用运行时(runtime)打印出UITextFiled的所有成员变量查看有没有关于占位文字UILabel类型的变量
- 打印得出 有一个私有成员变量placeholderLabel
- 可以利用KVC对私有成员变量 placeholderLabel进行属性值的修改
运行时打印UITextFiled的所有成员变量
#import <objc/runtime.h>
//获得所有的成员变量
unsigned int outCount = 0;
Ivar *ivars = class_copyIvarList([UITextFiled class], &outCount);
//打印出所有成员变量名
for (int i = 0; i<outCount; i++) {
Ivar ivar = ivars[i];
NSLog(@"%s",ivar_getName(ivar));
}
//手动释放
free(ivars);
- 使用KVC修改私有成员变量placeholderLabel的属性达到修改占位文字的效果
//先用KVC取出palceholderLabel,再修改(不如下面代码简洁)
// UILabel *palceholderLabel = [self valueForKey:@"placeholderLabel"];
// palceholderLabel.textColor = [UIColor grayColor];
//注意forKeyPath 和forKey 区别
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
三.UITextFiled之间的占位文字切换颜色
方法一:使用代理
注意
- 自己设置自己为代理,这种做法很SB,不要用,原因如下.
- 代理是一个类的属性,只能赋一个值
- 如果这时候需要在这个类中,
设置别的类的代理为这个类
就会产生冲突,这时候自己设置自己为代理
就会被覆盖永远不会是实现自己代理的方法
self.deleagte = self;
//实现代理方法
#pragma mark - <UITextFieldDelegate>
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
}
方法二:使用addTarget(必须继承于UIControl)
[self addTarget:self action:@selector(beginEditing) forControlEvents:UIControlEventEditingDidBegin];
[self addTarget:self action:@selector(endEditing) forControlEvents:UIControlEventEditingDidEnd];
- (void)beginEditing
{
[self setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];
}
- (void)endEditing
{
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
}
方法三:使用通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(beginEditing) name:UITextFieldTextDidBeginEditingNotification object:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(endEditing) name:UITextFieldTextDidEndEditingNotification object:self];
- (void)beginEditing
{
[self setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];
}
- (void)endEditing
{
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
方法四:重写系统的响应者方法becomeFirstResponder和resignFirstResponder
- (BOOL)becomeFirstResponder
{
[self setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];
return [super becomeFirstResponder];
}
- (BOOL)resignFirstResponder
{
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
return [super resignFirstResponder];
}
代码规范化处理
- 以上代码只设置了两种颜色(聚焦颜色和失去焦点的颜色)
#define placeholderDefaultColor [UIColor grayColor]
#define placeholderEditingColor [UIColor whiteColor]
#define placeholderColor @"placeholderLabel.textColor"