首先,是有簡單方法可以改變TextField和TextView的光標顏色的
textField.tintColor = someOtherColor;
// 或
[[UITextField appearance] setTintColor:someOtherColor]
由于面試時被問到以上方法之外的方法,當時沒想出來。
下面討論的是使用Runtime + KVC方法改變光標的顏色
1.首先,由于Apple的命名基本是見名知意的,所以先看一下UITextField這個類內成員變量的情況,看看能否找到與光標顏色對應的成員變量:
- (void)getIvarsOfUITextField
{
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([UITextField class], &count);
for (int i = 0; i < count; i++) {
Ivar ivar = ivars[i];
NSLog(@"%s---%s",ivar_getName(ivar),ivar_getTypeEncoding(ivar));
}
}
上面的代碼輸出了UITextField內的50個成員變量的變量名和TypeEncoding,但是經過一番查找,并沒有直接找到字面上和光標有關的變量。
對于一些這個類中已經有暴露出來的成員以及一些用于呈現文本或背景的視圖,如_backgroundView
、_floatingContentView
、_displayLabel
基本可以猜到與我們想要的實現無關。
2.挑選一些私有類進行嘗試,這里選了 _systemInputViewController---@"UISystemInputViewController"
和 _traits---@"UITextInputTraits"
這樣的可能選項。
在前面的方法中增加代碼:
- (void)getIvars
{
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([UITextField class], &count);
for (int i = 0; i < count; i++) {
Ivar ivar = ivars[i];
// NSLog(@"%s---%s",ivar_getName(ivar),ivar_getTypeEncoding(ivar));
if ( strcmp(ivar_getName(ivar), "_systemInputViewController") == 0) {
NSLog(@"%s",ivar_getTypeEncoding(ivar));
NSLog(@"=========_systemInputViewController start==========");
unsigned int subcount = 0;
NSString *fullClassString = [NSString stringWithCString:ivar_getTypeEncoding(ivar) encoding:NSUTF8StringEncoding];
fullClassString = [fullClassString substringFromIndex:2];
fullClassString = [fullClassString substringToIndex:fullClassString.length-1];
Class someClass = NSClassFromString(fullClassString);
Ivar *subVars = class_copyIvarList(someClass, &subcount);
for (int j= 0; j < subcount; j++) {
Ivar var = subVars[j];
NSLog(@"%s---%s",ivar_getName(var),ivar_getTypeEncoding(var));
}
NSLog(@"=========_systemInputViewController end==========");
}
if ( strcmp(ivar_getName(ivar), "_traits") == 0) {
NSLog(@"%s",ivar_getTypeEncoding(ivar));
NSLog(@"=========_traits start==========");
unsigned int subcount = 0;
NSString *fullClassString = [NSString stringWithCString:ivar_getTypeEncoding(ivar) encoding:NSUTF8StringEncoding];
fullClassString = [fullClassString substringFromIndex:2];
fullClassString = [fullClassString substringToIndex:fullClassString.length-1];
Class someClass = NSClassFromString(fullClassString);
Ivar *subVars = class_copyIvarList(someClass, &subcount);
for (int j= 0; j < subcount; j++) {
Ivar var = subVars[j];
NSLog(@"%s---%s",ivar_getName(var),ivar_getTypeEncoding(var));
}
NSLog(@"=========_traits end==========");
}
}
}
其中: _systemInputViewController---@"UISystemInputViewController"
這個成員變量的類中輸入:
可以看出 UISystemInputViewController
這個類中存放著一些和accessoryView、keyboard等相關的Controller和Constraints,并沒有我們想要的內容,至少從成員變量名上看起來是這樣的。
接下來 _traits---@"UITextInputTraits"
中輸出:
可以看到有insertionPointColor---@"UIColor"
和 insertionPointWidth---Q
這兩個成員變量,從命名上看很可能是我們想要的,加上insertionPointColor
的類型又是UIColor
。
- 驗證
在代碼中使用KVC對這個keyPath進行賦值驗證:
[self.field setValue:[UIColor redColor] forKeyPath:@"_traits.insertionPointColor"];
結果textfield的光標顏色果然改變了~
效果:
但TextField中還有一個_nonAtomTraits
成員為UITextInputTraits
類,下面用它來試試:
[self.field setValue:[UIColor redColor] forKeyPath:@"_nonAtomTraits.insertionPointColor"];
結果光標顏色并沒有發生改變,暫時它與_traits
。