最終設(shè)置UITextField的placeholder效果(實(shí)際效果可能比這好一點(diǎn)點(diǎn)...):

有需求1如下:
- 未點(diǎn)擊時UITextField的placeholder為淺灰色
- 點(diǎn)擊后,還未進(jìn)行輸入時,UITextField的placeholder變?yōu)樯罨疑?/li>
這個實(shí)現(xiàn)并不難:
- 通過通知或者重寫UITextField的響應(yīng)者處理方法(becomeFirstResponder/resignFirstResponder),都可以實(shí)現(xiàn)捕獲點(diǎn)擊時間
- UITextField設(shè)置placeholder可以使用以下屬性:
- 通過設(shè)置這個富文本屬性,可以得到豐富多彩的placeholder
- 通過設(shè)置這個富文本屬性,可以得到豐富多彩的placeholder
@NSCopying var attributedPlaceholder: NSAttributedString?
// 附帶光標(biāo)顏色屬性
var tintColor: UIColor!
但是需求2加了點(diǎn)東西:
- 點(diǎn)擊后,還未進(jìn)行輸入時,UITextField的placeholder文字左右進(jìn)行小幅度抖動
可以看到通過設(shè)置attributedPlaceholder,可以改變一些靜態(tài)的屬性,如顏色和文字大小。
但是如果需要里面的文字做一些簡單的抖動效果貌似就不行了,UITextField沒有提供相關(guān)屬性,我們也不知道placeholder是在何種控件中顯示的。
既然不知道placeholder是在何種控件中顯示,那就通過以下代碼打印出UITextField中所有的成員變量(函數(shù)參考runtime基礎(chǔ)元素解析),看看是否會有什么發(fā)現(xiàn):
Ivar *ivars = class_copyIvarList([UITextField class], &outCount);
for (int i = 0; i < outCount; i++) {
Ivar ivar = ivars[i];
NSLog(@"%s", ivar_getName(ivar));
}
free(ivars);
截取關(guān)鍵部分如下:

從字面上看,上面的
_placeholderLabel是否就是顯示placeholder的控件?測試實(shí)際結(jié)果的確是顯示placeholder的控件。
只要有了這個控件,那要做一些小抖動的動畫那就沒什么問題了,先獲取這個UILabel:
private var tpcPlaceholderLabel:UILabel? {
get {
return self.valueForKey("_placeholderLabel") as? UILabel
}
}
然后重寫UITextField的響應(yīng)者處理函數(shù):
// 成為第一響應(yīng)者
override func becomeFirstResponder() -> Bool {
if normalColor == nil {
normalColor = tpcPlaceholderLabel?.textColor
}
if selectedColor == nil {
selectedColor = tpcPlaceholderLabel?.textColor
}
tpcPlaceholderLabel?.textColor = selectedColor
UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.1, initialSpringVelocity: 10, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
tpcPlaceholderLabel?.transform = CGAffineTransformMakeTranslation(10, 0)
}, completion: nil)
return super.becomeFirstResponder()
}
// 放棄第一響應(yīng)者
override func resignFirstResponder() -> Bool {
tpcPlaceholderLabel?.transform = CGAffineTransformIdentity
tpcPlaceholderLabel?.textColor = normalColor
return super.resignFirstResponder()
}
這樣就可以做簡單的抖動了
還有一點(diǎn),根據(jù)上面打印的UITextField成員變量,看到了_displayLabel,這個就是在鍵盤輸入后顯示文字的UILabel了。這個屬性可以用來干嘛?
我想,可能會有這么一種需求(不過可能沒有),就是用戶輸入錯誤時,UITextField中已經(jīng)輸入的文字做簡單左右抖動,并且顏色變?yōu)榧t色,以間接的形式,輔助提醒用戶,這一欄輸錯了,而不是彈出一個HUB。
由于UITextField內(nèi)部做了某些處理,所以無法在成為第一響應(yīng)者時做一些動作,那么,就在放棄第一響應(yīng)者函數(shù)中。
相關(guān)代碼如下:
// 設(shè)置一個在放棄第一響應(yīng)者調(diào)用的閉包屬性
var operateWhenResignFirstResponder: (() -> ())?
// 在func resignFirstResponder() -> Bool函數(shù)中調(diào)用
if let operate = operateWhenResignFirstResponder {
operate()
}