应用背景
在项目中遇到的问题: 想要实现
UITextField
类型对象的占位文字颜色变化
, 有账号、密码两个不同的UITextField
对象, 当用户去准备键入账号时, 账号输入框的占位文字颜色变为白色.
实现思路
这个效果的实现笔者想到三种
1. 使用运行时来获取UIKit库中UITextField.h文件中并没有暴露出来的隐藏成员变量来获取
2. 使用textField的attributedPlaceholder属性
3. 不适用placeholder, 改使用UILabel来实现占位
为何要使用运行时实现
首先我们可以看一些UITextField.h
的属性
可以发现我们可以找到NSString 类型的placeholder 属性, 但是没有可以设置placeholder颜色的的属性.
这时候就用到了运行时.
解决: 运行时查找隐藏起来的成员变量
考虑到不只是登录界面使用到变色的占位文字, 故
使用一个分类来实现
, 姑且命名为CHTextField
, 继承自UITextField
.
//
// CHTextField.m
// baodanFenqi
// Copyright © 2017年 逯帅. All rights reserved.
#import "CHTextField.h"
#import <objc/runtime.h>
@implementation CHTextField
+ (void)initialize {
unsigned int count = 0;
// 拷贝出所有成员变量的列表, ivars是指向首个成员变量的指针
Ivar *ivars = class_copyIvarList([UITextField class], &count);
for (int i = 0; i < count; i++) {
// 取出成员变量
Ivar ivar = *(ivars + i);
// Ivar ivar = ivars[i];
// 打印成员变量的名字
NSLog(@"%s", ivar_getName(ivar));
// 返回一个实例变量的字符串类型
NSLog(@"%s", ivar_getTypeEncoding(ivar));
}
// class_copyIvarList 之后需要释放
free(ivars);
}
@end
打印结果如下: 61个
_textStorage
_borderStyle
_minimumFontSize
_delegate
_background
_disabledBackground
_clearButtonMode
_leftView
_leftViewMode
_rightView
_rightViewMode
_traits
_nonAtomTraits
_fullFontSize
_padding
_selectionRangeWhenNotEditing
_scrollXOffset
_scrollYOffset
_progress
_clearButton
_clearButtonOffset
_leftViewOffset
_rightViewOffset
_backgroundView
_disabledBackgroundView
_systemBackgroundView
_floatingContentView
_contentBackdropView
_fieldEditorBackgroundView
_fieldEditorEffectView
_displayLabel
_placeholderLabel
_suffixLabel
_prefixLabel
_iconView
_label
_labelOffset
_overriddenPlaceholder
_overriddenPlaceholderAlignment
_interactionAssistant
_selectGestureRecognizer
_inputView
_inputAccessoryView
_recentsAccessoryView
_systemInputViewController
_atomBackgroundView
_textFieldFlags
_deferringBecomeFirstResponder
_avoidBecomeFirstResponder
_setSelectionRangeAfterFieldEditorIsAttached
_animateNextHighlightChange
_cuiCatalog
_cuiStyleEffectConfiguration
_roundedRectBackgroundCornerRadius
_adjustsFontForContentSizeCategory
_tvUseVibrancy
_disableTextColorUpdateOnTraitCollectionChange
_baselineLayoutConstraint
_baselineLayoutLabel
_tvCustomTextColor
_tvCustomFocusedTextColor
我们从中可以看到一个成员变量向我们招手:
_placeholderLabel
@"UITextFieldLabel"
代码实现
[field setValue:[UIColor whiteColor] forKey:@"_placeholderLabel.textColor"];
// 设置光标颜色和文字颜色一致
self.tintColor = self.textColor;
利用textField的attributedPlaceholder属性实现
NSString *place = @"请输入您的昵称";
NSMutableAttributedString *placeAtt = [[NSMutableAttributedString alloc]initWithString:place];
[placeAtt addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:NSMakeRange(0, place.length)];
field.attributedPlaceholder = placeAtt;
注注注注注: 这里有更多富文本属性