美文网首页
知识点总结13:textField占位文字的颜色的修改

知识点总结13:textField占位文字的颜色的修改

作者: 枫之叶_小乙哥 | 来源:发表于2017-02-07 21:21 被阅读95次

    textField修改占位文字的方案共有3种:

    • 方案一:富文本(给textField的attributedText属性赋值)
    /*在textField的自定义控件中*/
    #import "ZGKTextField.h"
    
    @implementation ZGKTextField
    
    - (void)awakeFromNib{
        [super awakeFromNib];
        // 0.设置光标颜色
        self.tintColor = [UIColor whiteColor];
        // 0.设置输入文字颜色
        self.textColor = [UIColor redColor];
        
        // 1.设置占位文字颜色
        // 1.1 设置文字属性(不可变富文本NSAttributedString)
        // self.placeholder = @"占位文字";
        /**** attributedPlaceholder的优先级比palceholder的高 ****/
        NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
        /**** attributes的key都在NSAttributedString.h文件里面 ****/
        /*
         设置占位文字为黄色
         设置背景颜色为紫色
         */
        attributes[NSForegroundColorAttributeName] = [UIColor whiteColor];
    //    attributes[NSBackgroundColorAttributeName] = [UIColor purpleColor];
        /**** 将布尔类型包装成对象 ****/
    //    attributes[NSUnderlineStyleAttributeName] = @YES;
        /**** self.placeholder xib设置的占位文字 ****/
        NSAttributedString *attributedStr = [[NSAttributedString alloc] initWithString:self.placeholder attributes:attributes];
        
        // 1.2给占位文字赋值(可以是palceholder或者attributedPlacedholder)
        self.attributedPlaceholder = attributedStr;
       
        
    //    // 2.设置文字属性(可变富文本NSMutableAttributedString)
    //    NSMutableAttributedString *mutableAttriStr = [[NSMutableAttributedString alloc] initWithString:self.placeholder];
    //    NSMutableDictionary *attributes2 = [NSMutableDictionary dictionary];
    //    attributes2[NSForegroundColorAttributeName] = [UIColor greenColor];
    //    // 不同属性进行富文本格式的叠加
    //    [mutableAttriStr addAttributes:attributes range:NSMakeRange(0, 1)];
    //    [mutableAttriStr addAttributes:attributes2 range:NSMakeRange(1, 1)];
    //    // 这个才有效
    //    [mutableAttriStr setAttributes:attributes2 range:NSMakeRange(0, 1)];
    //    self.attributedPlaceholder = mutableAttriStr;
        
        // 3.设置默认输入文字(xib设置了,所以此处不用设置)
        self.attributedText = [[NSAttributedString alloc] initWithString:@"" attributes:nil];
    }
    
    
    总结:

    1.textField的属性attributedPlaceholder的优先级比placeholder的高,所以设置带有属性的占位文字即可改变占位文字的大小和颜色

    2.textField的属性attributedPlaceholder可以设置不可变富文本NSAttributedString,也可以设置可变富文本NSMutableAttributedString,可变富文本可以设置多个Attributes属性

        // 2.设置文字属性(可变富文本NSMutableAttributedString)
        NSMutableAttributedString *mutableAttriStr = [[NSMutableAttributedString alloc] initWithString:self.placeholder];
        NSMutableDictionary *attributes2 = [NSMutableDictionary dictionary];
        attributes2[NSForegroundColorAttributeName] = [UIColor greenColor];
        // 不同属性进行富文本格式的叠加
        [mutableAttriStr addAttributes:attributes range:NSMakeRange(0, 1)];
        [mutableAttriStr addAttributes:attributes2 range:NSMakeRange(1, 1)];
        // 这个才有效
        [mutableAttriStr setAttributes:attributes2 range:NSMakeRange(0, 1)];
        self.attributedPlaceholder = mutableAttriStr;
    

    3.富文本的addAttributes:方法和setAttributes:方法是不同的,前者可以叠加,后者是set方法,只能有一个值,不能叠加属性.

    • 方案二:重写textField的- (void)drawPlaceholderInRect:(CGRect)rect方法
    #pragma mark - 重写
    /**** 先调用 ****/
    // 该方法控制占位文字的大小和位置
    // bounds是默认的占位文字的bounds
    - (CGRect)placeholderRectForBounds:(CGRect)bounds{
        // textField默认的rect==bounds
        NSLog(@"%@", NSStringFromCGRect(bounds));
        // 在这里修改占位文字的大小和位置
    //    return CGRectMake(0, 0, 60, 10);
        return bounds;
    }
    
    /**** 后调用 ****/
    // 该方法控制占位文字的格式及大小和位置
    // ===>rect是上面方法传入的rect,上面方法修改了rect,则这个方法传入的rect也会改变
    - (void)drawPlaceholderInRect:(CGRect)rect{
        NSLog(@"2---%@", NSStringFromCGRect(rect));
        
        // 0.rect
        CGRect placeholderRect;
        placeholderRect.size.width = rect.size.width;
        /**** self.font是占位文字或者光标文字的字体大小,lineHeight用于计算字体的行高 ****/
        placeholderRect.size.height = self.font.lineHeight;
        placeholderRect.origin.x = 0;
        placeholderRect.origin.y = (rect.size.height - self.font.lineHeight) * 0.5;
        
        // 1.attributes
        NSMutableDictionary *attriDict = [NSMutableDictionary dictionary];
        /**** 字体大小和xib的字体大小要一致,不然self.font.lineHeight计算行高就不管用了 ****/
        attriDict[NSFontAttributeName] = [UIFont systemFontOfSize:14];
        attriDict[NSForegroundColorAttributeName] = [UIColor blueColor];
        
        // 2.1 drawInRect
    //    [self.placeholder drawInRect:placeholderRect withAttributes:attriDict];
        
        // 2.1 drawInPoint
    //    [self.placeholder drawAtPoint:CGPointMake(0, 0) withAttributes:attriDict];
        [self.placeholder drawAtPoint:CGPointMake(0, placeholderRect.origin.y) withAttributes:attriDict];
    
    }
    

    特别注意:
    1.运行时,程序会先执行- (CGRect)placeholderRectForBounds:(CGRect)bounds方法,后执行- (void)drawPlaceholderInRect:(CGRect)rect方法,前者是修改占位文字的大小和位置的,不修改则为默认的bounds.后者是重绘占位文字,可以用drawInRect或者drawAtPoint方法,该方法传入的rect是前者返回的值.

    • 方案三:运行时通过KVC, 给textFiled的placeholderLabel.textColor赋值
    #import "ZGKTextField.h"
    #import <objc/runtime.h>
    @implementation ZGKTextField
    
    - (void)awakeFromNib{
        [super awakeFromNib];
        // 0.设置光标颜色
        self.tintColor = [UIColor whiteColor];
        // 0.设置输入文字颜色
        self.textColor = [UIColor redColor];
        // 方法3:(从子控件入手)
        /**** ******************************************************************** ****/
    
        // 1.因为占位文字在没有输入时,一直存在, 一输入字,占位文字就会消失,所以我们猜测占位文字是UITextField的一个子控件(可以输入文字,并用调试小面包来观察)
        // 直接打印,并不能打印出子控件
    //        NSLog(@"textField的子控件---%@", self.subviews);
    
        
        // 2.直接打印,因为从xib加载textField时,textField内部的自控件可能还没有添加,因为延迟打印看看
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            // 1.打印子控件
            // NSLog(@"textField的子控件---%@", self.subviews);
            // 2.通过上面打印发现:textField只有一个子控件,因此将他的类型打印出来
            NSLog(@"textField的子控件---%@", [self.subviews.lastObject class]);
            // 3.取出UITextFieldLabel,给其的textColor属性赋值就可以改变占位文字的颜色
            // UITextFieldLabel是私有类,不能用,所以只能找他的父类
    //        UITextFieldLabel *textFieldLabel = self.subviews.lastObject;
            // 4.找到 UITextFieldLabel的父类是UILabel(父类:superclass, 父控件:superview)
            NSLog(@" UITextFieldLabel.superView = %@", self.subviews.lastObject.superclass);
            /*
             2017-01-29 00:25:10.846 MyProject[4298:201733] textField的子控件---UITextFieldLabel
             2017-01-29 00:25:10.847 MyProject[4298:201733]  UITextFieldLabel.superView = UILabel
             */
            
            // 5.多态, 用父类来接收子类对象,并改变对象的属性值
            UILabel *textFieldLabel = self.subviews.lastObject;
            
            // 验证第四种方法,所以要注释掉,因为是延迟0.1秒执行的
    //        textFieldLabel.textColor = [UIColor whiteColor];
        });
        
        // 上述方法的弊端:
        /*
        // 2017-01-29 00:57:33.584 MyProject[4557:217054] textField的子控件---(null)
        // 2017-01-29 00:57:33.584 MyProject[4557:217054]  UITextFieldLabel.superView = (null)
         2017-01-29 00:57:33.628 MyProject[4557:217054] textField的子控件---UITextFieldLabel
         2017-01-29 00:57:33.628 MyProject[4557:217054]  UITextFieldLabel.superView = UILabel
         2017-01-29 00:57:33.661 MyProject[4557:217054] textField的子控件---UITextFieldLabel
         2017-01-29 00:57:33.662 MyProject[4557:217054]  UITextFieldLabel.superView = UILabel
         2017-01-29 00:57:33.671 MyProject[4557:217054] textField的子控件---UITextFieldLabel
         2017-01-29 00:57:33.672 MyProject[4557:217054]  UITextFieldLabel.superView = UILabel
         */
        // 1.不知道什么时候textfield才添加了子控件UITextFieldLabel,只能一定时间以后才执行,延迟执行的时间不好控制
        // 2.该控件不像控制器,可以在viewWillAppear方法中做事情
        // 3.通过数组(self.subviews)去拿对象也不靠谱,本案例中,刚好只有一个子控件UITextFieldLabel,如果有多个子控件,则不能用lastObject去取
        /**** ******************************************************************** ****/
    
        // 方法4:(从属性入手)
        /**** ******************************************************************** ****/
        // 1.1.因为占位文字在没有输入时,一直存在, 一输入字,占位文字就会消失,所以我们猜测TextField里面有个属性强引用UITextfieldLabel,所以我们可以用kvc去赋值(无论是公共属性还是私有属性)
    //    UILabel *label = [self valueForKeyPath:@"placeholderLabel"];
    //    label.textColor = [UIColor yellowColor];
    //    
        /**** ******************************************************************** ****/
    
        
        // 方法5:(相比方法3和4,推荐使用方法5:从属性入手)
        /**** ******************************************************************** ****/
        // 1.1 因为方法4中,我们可能无法得知是哪个属性强引用UITextfieldLabel,所以我们可以用运行时方法来找出相关属性名
        
        // 2.获取属性列表
        // c语言
        unsigned int count;
        // ivarList是指针,指向数组, 传入的参数是指针&count
        Ivar *ivarList = class_copyIvarList([UITextField class], &count);
        
        // 3.打印属性列表
        for (int i= 0; i< count; i++) {
            Ivar ivar = ivarList[i];
            /*
             2017-01-29 00:55:40.856 MyProject[4520:215206] 属性列表31---_placeholderLabel
             */
            NSLog(@"属性列表%d---%s", i, ivar_getName(ivar));
        }
        
        // 4.释放指针
        free(ivarList);
        
        // 4.设置占位文字的颜色为绿色
        [self setValue:[UIColor greenColor] forKeyPath:@"placeholderLabel.textColor"];
     }
    

    相关文章

      网友评论

          本文标题:知识点总结13:textField占位文字的颜色的修改

          本文链接:https://www.haomeiwen.com/subject/myymittx.html