iOS日常知识储备UITextFieldiOS开发实用技术

关于设置TextFiled中占位文字的颜色的几个方法

2016-02-28  本文已影响1357人  Alexander

欢迎"@WilliamAlex大叔"一起讨论iOS技术

项目需求: 使用textField时,占位文字默认是黑色的,我们的需求是当开始编辑时,让占位文字和光标变成红色(或其他颜色)

思路: textField和button类似,内部都拥有子控件,在OC机制中,所有控件内部都是以懒加载的形式添加的.我们可以拿到textField中的子控件label,通过监听textField的状态,设置内部子控件label的样式.

// 1, 首先在xib中描述登录界面

// 2, 新建一个继承于UITextField的类,将xib中的所有TextFiled都绑定这个类.
// 方法1: 通过富文本字符串来设置样式

- (void)awakeFromNib
{

    // 1, 设置光标的颜色
    self.tintColor = [UIColor whiteColor];

    // 2, 监听textField的开始编辑状态
    [self addTarget:self action:@selector(textFieldBeginEditing) forControlEvents:UIControlEventEditingDidBegin];

    // 3, 监听textField的结束编辑
    [self addTarget:self action:@selector(textFieldEndEditing) forControlEvents:UIControlEventEditingDidEnd];

    // 4, 描述占位文字属性
    NSMutableDictionary *attr = [NSMutableDictionary dictionary];
    attr[NSForegroundColorAttributeName] = [UIColor darkGrayColor];

    // 5, 富文本属性
    NSAttributedString *attribute = [[NSAttributedString alloc] initWithString:self.placeholder attributes:attr];

    self.attributedPlaceholder = attribute;

}

#pragma mark - 事件监听方法

// 监听开始编辑
- (void)textFieldBeginEditing {

    // 1, 描述占位文字属性
    NSMutableDictionary *attr = [NSMutableDictionary dictionary];
    attr[NSForegroundColorAttributeName] = [UIColor whiteColor];

    // 2, 富文本属性
    NSAttributedString *attribute = [[NSAttributedString alloc] initWithString:self.placeholder attributes:attr];

    self.attributedPlaceholder = attribute;

}

// 监听结束编辑
- (void)textFieldEndEditing {

    // 4, 描述占位文字属性
    NSMutableDictionary *attr = [NSMutableDictionary dictionary];
    attr[NSForegroundColorAttributeName] = [UIColor darkGrayColor];

    // 5, 富文本属性
    NSAttributedString *attribute = [[NSAttributedString alloc] initWithString:self.placeholder attributes:attr];

    self.attributedPlaceholder = attribute;
}

方法二 :

- (void)awakeFromNib
{
    UITextField *textFiled;
    // 1.设置光标
    self.tintColor = [UIColor whiteColor];

    // 监听开始编辑
    [self addTarget:self action:@selector(textBegin) forControlEvents:UIControlEventEditingDidBegin];

    // 监听结束编辑
    [self addTarget:self action:@selector(textEnd) forControlEvents:UIControlEventEditingDidEnd];

    // 根据属性名获取这个属性的值
    UILabel *placeholderLabel = [self valueForKeyPath:@"placeholderLabel"];

    placeholderLabel.textColor = [UIColor lightGrayColor];

}

// 文本框开始编辑
- (void)textBegin
{
    // 修改占位文字样式
    // 根据属性名获取这个属性的值
    UILabel *placeholderLabel = [self valueForKeyPath:@"placeholderLabel"];

    placeholderLabel.textColor = [UIColor whiteColor];
}

// 文本框结束编辑
- (void)textEnd
{
    // 根据属性名获取这个属性的值
    UILabel *placeholderLabel = [self valueForKeyPath:@"placeholderLabel"];

    placeholderLabel.textColor = [UIColor lightGrayColor];
}

封装代码

- (void)awakeFromNib
{
    // 1.设置光标
    self.tintColor = [UIColor whiteColor];

    // 监听开始编辑
    [self addTarget:self action:@selector(textBegin) forControlEvents:UIControlEventEditingDidBegin];

    // 监听结束编辑
    [self addTarget:self action:@selector(textEnd) forControlEvents:UIControlEventEditingDidEnd];

    // 根据属性名获取这个属性的值
    self.placeholderColor = [UIColor lightGrayColor];
}

// 文本框开始编辑
- (void)textBegin
{
    // 修改占位文字样式
    self.placeholderColor = [UIColor whiteColor];
}

// 文本框结束编辑
- (void)textEnd
{
    self.placeholderColor = [UIColor lightGrayColor];
}

.h文件
// 需要将属性定义在.h文件中,方便外界调用
// 设置占位文字颜色
@property UIColor *placeholderColor;
#import "UITextField+Placeholder.h"
#import <objc/message.h>
// runtime:主要目的操作系统的类

// OC系统自带控件中,所有的子控件都是懒加载
@implementation UITextField (Placeholder)

+ (void)load
{
    Method setPlaceholderMethod = class_getInstanceMethod(self, @selector(setPlaceholder:));
     Method wg_setPlaceholderMethod = class_getInstanceMethod(self, @selector(wg_setPlaceholder:));

    // 交互方法
    method_exchangeImplementations(setPlaceholderMethod, wg_setPlaceholderMethod);

}

// 设置占位文字颜色
- (void)setPlaceholderColor:(UIColor *)placeholderColor
{
    // 1.保存占位文字颜色到系统的类,关联
    // object:保存到哪个对象中
    // key:属性名
    // value:属性值
    // policy:策略
    objc_setAssociatedObject(self, @"placeholderColor", placeholderColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    UILabel *placeholderLabel = [self valueForKeyPath:@"placeholderLabel"];
    placeholderLabel.textColor = placeholderColor;
}

- (UIColor *)placeholderColor
{
    return objc_getAssociatedObject(self, @"placeholderColor");
}

- (void)wg_setPlaceholder:(NSString *)placeholder
{
    // 设置占位文字
    [self wg_setPlaceholder:placeholder];

    // 设置占位文字颜色
    self.placeholderColor = self.placeholderColor;
}

使用Target监听TextField内部控件的私有属性.

// 1, 获取私有属性
    // 运行时获取类中的私有属性
    unsigned int count;
    // 运行时打印出文本框中的所有成员属性
    Ivar *ivarList = class_copyIvarList([UITextField class], &count);
    for (int i =0; i< count; i++) {
        Ivar ivar = ivarList[i];

        NSLog(@"%s",ivar_getName(ivar));
    }
    free(ivarList);

// 2, 找到对应的私有属性,将它设置为一个宏
static NSString * const WGPlaceholderLabel = @"placeholderLabel.textColor";

    // 设置占位文字原有颜色
    [self setValue:[UIColor grayColor] forKeyPath:WGPlaceholderLabel];

    // 监听文本框开始编辑
    [self addTarget:self action:@selector(editingBegin) forControlEvents:UIControlEventEditingDidBegin];

    // 监听文本框结束编辑
    [self addTarget:self action:@selector(editingEnd) forControlEvents:UIControlEventEditingDidEnd];

#pragma mark - 监听文本框的编辑状态

- (void)editingBegin{

    [self setValue:[UIColor whiteColor] forKeyPath:WGPlaceholderLabel];
}

- (void)editingEnd {

   [self setValue:[UIColor grayColor] forKeyPath:WGPlaceholderLabel];
}

代理(不推荐使用)

/*
 总结: 本章是用代理的方式监听文本框的编辑状态,然后通过拿到UITextField中的私有的_placeholderLabel属性,给私有属性赋值即可,通过运行时获取查看其内部的所有私有属性,然后通过KVC赋值;
 */

#import "WGLoginRegisterTextFiled.h"
#import <objc/message.h>

static NSString * const WGPlaceholderLabel = @"_placeholderLabel.textColor";

@interface WGLoginRegisterTextFiled () <UITextFieldDelegate>
@end
@implementation WGLoginRegisterTextFiled

- (void)awakeFromNib {

    // 设置光标颜色
    self.tintColor = [UIColor cyanColor];

    // 通过运行时获取TextFiled的内部私有属性
    unsigned int count ;
    Ivar *ivarList = class_copyIvarList([UITextField class], &count);
    // 遍历UITextField的所有属性,ivarList(指针)实质是一个数组

    for (int i = 0; i < count; i++) {

        // 获取每一个属性
        Ivar ivar = ivarList[i];

        NSLog(@"%s",ivar_getName(ivar));  // "%s"原因是运行时是一个C语言的语法

    }

    // 销毁运行时创建的ivarList
    free(ivarList);

    // 通过KVC将属性取出来并赋值
    [self setValue:[UIColor grayColor] forKeyPath:WGPlaceholderLabel];

    // 设置代理
    self.delegate = self; // 自己成为自己的代理,在实际开发中不这样写,这和代理的原理意义上违背了

}

#pragma mark - 设置代理的方法

// 开始编辑
- (void)textFieldDidBeginEditing:(UITextField *)textField {

    // KVC
    [self setValue:[UIColor whiteColor] forKeyPath:WGPlaceholderLabel];

}

// 结束编辑
- (void)textFieldDidEndEditing:(UITextField *)textField {

    [self setValue:[UIColor grayColor] forKeyPath:WGPlaceholderLabel];

}

根据某些控件特有的方法或者属性来设置

/*
 分析:UITextField有一个特有的属性,就是响应者属性,通过重写成为第一响应者和辞去第一响应者来给占位文字设置颜色


 */
#import "WGLoginRegisterTextFiled.h"
#import <objc/message.h>

static NSString * const WGPlaceholderLabel = @"_placeholderLabel.textColor";

@interface WGLoginRegisterTextFiled () <UITextFieldDelegate>
@end
@implementation WGLoginRegisterTextFiled

- (void)awakeFromNib {

    // 设置光标颜色
    self.tintColor = [UIColor cyanColor];

    // 通过KVC将属性取出来并赋值
    [self setValue:[UIColor grayColor] forKeyPath:WGPlaceholderLabel];

    // 调用时刻: 当成为第一响应者 /获取焦点 /弹出键盘
    [self becomeFirstResponder];

    // 调用时刻: 当失去第一响应者 /获取焦点 /弹出键盘
    [self resignFirstResponder];

}

#pragma mark - 设置代理的方法


// 调用时刻: 当成为第一响应者 /获取焦点 /弹出键盘
- (BOOL)becomeFirstResponder {

    [self setValue:[UIColor whiteColor] forKeyPath:WGPlaceholderLabel];

    return [super becomeFirstResponder];
}

// 调用时刻: 当失去第一响应者 /获取焦点 /弹出键盘
- (BOOL)resignFirstResponder {

    [self setValue:[UIColor grayColor] forKeyPath:WGPlaceholderLabel];

   return [super resignFirstResponder];

}
@end

上一篇 下一篇

猜你喜欢

热点阅读