自定义UITextField达到你要的效果

  在项目过程中,你的登录界面的UITextField用系统自带的已经不能满足HR的要求,光标需要其他颜色,placeholder需要别的颜色,点击后placeholder的颜色要改变,这些属性的改变是自定义的UITextField才能完成的。下面来介绍一些修改UITextField一些属性的方法。当然,首先你得创建一个继承UITextField的类,然后我们才能在类中写方法。

  如果你只是想要修改一点点地方,又不喜欢用自定义,那么可以用下面的方法,当然下面的方法局限性挺大的,不如自定义的功能强大。

                         

    // 文字属性,直接修改全部placeholder的文字颜色
    NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
    attrs[NSForegroundColorAttributeName] = [UIColor grayColor];

    // NSAttributedString : 带有属性的文字(富文本技术)
    NSAttributedString *placeholder = [[NSAttributedString alloc] initWithString:@"手机号" attributes:attrs];
    self.textField.attributedPlaceholder = placeholder;

    // 可以给每一个文字都修改颜色
    NSMutableAttributedString *placehoder = [[NSMutableAttributedString alloc] initWithString:@"手机号"];
    [placehoder setAttributes:@{NSForegroundColorAttributeName : [UIColor whiteColor]} range:NSMakeRange(0, 1)];
    [placehoder setAttributes:@{
                                NSForegroundColorAttributeName : [UIColor yellowColor],
                                NSFontAttributeName : [UIFont systemFontOfSize:30]
                                } range:NSMakeRange(1, 1)];
    [placehoder setAttributes:@{NSForegroundColorAttributeName : [UIColor redColor]} range:NSMakeRange(2, 1)];
    self.phoneField.attributedPlaceholder = placehoder;

        

  如果只是修改placeholder的文字颜色,你用xib的设置的话那就在awakeFromXib方法中用setValue:forKeyPath: 这种方法来修改placeholder的文字颜色。如果是纯代码,那就在初始化方法中实现。xib的话,需要让UITextField继承你自定义的textField。

  

  还能设置光标的颜色,默认是蓝色的。

- (void)awakeFromNib {
    UILabel *placeholderLabel = [self valueForKeyPath:@"_placeholderLabel"];
    placeholderLabel.textColor = [UIColor redColor];
    
    // 设置光标颜色和文字颜色一致
    self.tintColor = self.textColor;
}

  

   但是高亮状态下的我们还没有写,既然 TA 有聚焦(高亮)状态,那么应该有一个方法有可以设置highlighted。

  下面代码的确可以实现聚焦状态下文字颜色改变,但是改变后就改变不回来了。

- (void)setHighlighted:(BOOL)highlighted {
    // 修改placeholder(占位)文字颜色
    [self setValue:self.textColor forKeyPath:@"_placeholderLabel.textColor"];
}

  

    既然这样不能改回来,那我们就可以重写成为第一响应者与放弃第一响应者的方法。

// 建议定义这样,使用方便
static NSString * const SQPlacerholderColorKeyPath = @"_placeholderLabel.textColor";

/*
 ** 修改一下这个方法
 */
- (void)awakeFromNib {
//    UILabel *placeholderLabel = [self valueForKeyPath:@"_placeholderLabel"];
//    placeholderLabel.textColor = [UIColor redColor];
    
    // 不成为第一响应者
    [self resignFirstResponder];
    
    // 设置光标颜色和文字颜色一致
    self.tintColor = self.textColor;
}

/**
 *  当前文本框聚焦时就会调用
 */
- (BOOL)becomeFirstResponder {
    // 修改placeholder(占位)文字颜色
    [self setValue:self.textColor forKeyPath:SQPlacerholderColorKeyPath];
    return [super becomeFirstResponder];
}

/**
 *  当前文本框失去焦点时就会调用
 */
- (BOOL)resignFirstResponder {
    // 修改placeholder(占位)文字颜色
    [self setValue:[UIColor grayColor] forKeyPath:SQPlacerholderColorKeyPath];
    return [super resignFirstResponder];
}

  利用上面的这个方法,就可以实现UITextField你想要的效果了。但是UITextField的成员变量我们是看不到的,这个时候我们就可以用runtime来查看到底有哪些成员变量,这样我们就可以用setValue:forKeyPath: 来赋值了。想要使用runtime我们需要导入一个头文件  #import <objc/runtime.h>  ,下面有两个方法,可以访问成员变量跟属性。

/**
 *  运行时(Runtime):苹果官方一套C语言库
 能做很多底层操作(比如访问隐藏的一些成员变量成员方法...)
 */
+ (void)getProperties {
    unsigned int count = 0;
    
    objc_property_t *properties = class_copyPropertyList([UITextField class], &count);
    
    for (int i = 0; i < count; i++) {
        // 取出属性
        objc_property_t property = properties[i];
        
        // 打印属性名字
        SQLog(@"%s", property_getName(property));
        
        // 打印属性类型
        SQLog(@"%s",property_getAttributes(property));
    }
    
    free(properties);
}

- (void)getIvars {
    unsigned int count = 0;
    
    // 拷贝出所有的成员变量列表
    Ivar *ivars = class_copyIvarList([UITextField class], &count);
    
    
    for (int i = 0; i < count; i++) {
        // 取出成员变量
        //        Ivar ivar = *(ivars + i);
        Ivar ivar = ivars[i];
        
        // 打印成员变量名字
        SQLog(@"%s", ivar_getName(ivar));
    }
    
    // 释放
    free(ivars);
}

  runtime其实有很多的方法,这里就介绍这么点,想要了解更多,可以查看官方文档,里面有详细的介绍,网上也有已经翻译好的中文文档,因为这个比较重要,翻译的比较好,当然这里没有传送门。

原文地址:https://www.cnblogs.com/shensq/p/5362873.html