zoukankan      html  css  js  c++  java
  • 自定义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其实有很多的方法,这里就介绍这么点,想要了解更多,可以查看官方文档,里面有详细的介绍,网上也有已经翻译好的中文文档,因为这个比较重要,翻译的比较好,当然这里没有传送门。

  • 相关阅读:
    Mysql命令行中文乱码的解决方法
    Office 开发版本号与版本对应关系
    问题Initial SessionFactory creation failed.org.hibernate.HibernateException: /hibernate.cfg.xml not found解决方法
    -Dmaven.multiModuleProjectDirectory system propery is not set问题解决
    错误:Unsupported major.minor version 51.0(jdk版本错误)的解决方法
    把disable maven nature后的项目,恢复菜单呈现出来(Convert to Maven Project)
    mysql免安装版配置使用
    windows下安装使用WGET
    [转]maven编译时出现读取XXX时出错invalid LOC header (bad signature)
    云计算openstack共享组件——Memcache 缓存系统
  • 原文地址:https://www.cnblogs.com/shensq/p/5362873.html
Copyright © 2011-2022 走看看