文章鏈接
UITextField本身自帶三個(gè)消息類型:
UITextFieldTextDidBeginEditingNotification
UITextFieldTextDidChangeNotification
UITextFieldTextDidEndEditingNotification
至于作用嘛,看名字就知道了啦~~
因?yàn)榈卿浗缑嫘枰?,所以今天就稍微的了解了一? =,然后怕又會(huì)忘記了,所以就記錄下來了。
接下來講講怎么使用這三個(gè)東西。
首先,我想實(shí)現(xiàn)一個(gè)這樣的功能,就是以下(還在很后面呢)的登錄界面,登錄按鈕在用戶名或者密碼為空的時(shí)候是無法點(diǎn)擊的,當(dāng)用戶名和密碼都不是空的時(shí)候,登錄按鈕才可以點(diǎn)擊。而且最重要的是這個(gè)過程是動(dòng)態(tài)的,不能等用戶名或密碼輸完了后在判斷,于是代理方法里的textFieldDidEndEditing就帕斯掉了,那么不還有一個(gè)shouldChangeCharactersInRange方法嗎?這家伙不也是可以實(shí)時(shí)監(jiān)控輸入內(nèi)容的嗎?非得用nsnotification?嗯,你可以自己嘗試下。。。。。
于是我就用UITextFieldTextDidChangeNotification來實(shí)現(xiàn)我的功能啦,如名所說,只要文本框發(fā)生變化就會(huì)觸發(fā)消息。
首先添加觀察者, 記得不用的時(shí)候要解除掉通知哦。:
//ViewContrller.swift
override func viewDidLoad() {
super.viewDidLoad()
......
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.loginStatus(_:)), name: UITextFieldTextDidChangeNotification, object: nil)
// Do any additional setup after loading the view.
}
override func viewDidDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UITextFieldTextDidChangeNotification, object: nil)
}
實(shí)現(xiàn)loginStatus方法。搞定。
//ViewContrller.swift
func loginStatus(sender: NSNotification) {
//sender.object!.isEqual(self.userText)
//sender.object!.isEqual(self.pwdText)
if (!self.userText.text!.isEmpty && !self.pwdText.text!.isEmpty) {
self.btn_Login.enabled = true
} else {
self.btn_Login.enabled = false
}
}
以下是該方法的原型
func addObserver(observer: AnyObject, selector aSelector: Selector, name aName: String?, object anObject: AnyObject?)
讓本菜鳥稍稍作下解釋:
observer: 觀察者,嗯。
selector: 選擇器, 嗯。
name: 消息名,嗯。
object: 對象, 嗯。(哎呀,千萬不要扔石頭= =,很通俗易懂的解釋有木有)
這里的object指的是發(fā)送消息的對象,如果是nil的話,如我上面所寫的,那么所有的UITextField對象都可以發(fā)送消息,也就是我的userText和pwdText啦,如果指明對象的話,那么只有注冊的對象才能發(fā)哦。如下,self.pwdText將不會(huì)發(fā)送消息,因?yàn)闆]有注冊嘛!還有當(dāng)多個(gè)對象共用同一個(gè)選擇器時(shí),可以通過sender.object!.isEqual()判斷是哪個(gè)對象哦。
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.loginStatus(_:)), name: UITextFieldTextDidChangeNotification, object: self.userText)
通過上面的倆照片, 細(xì)心的同學(xué)可能發(fā)現(xiàn)了,當(dāng)我編輯文本框時(shí)文本框下面的線顏色變了耶,很炫酷有木有(好吧,我知道其實(shí)很菜= =)
其實(shí)這個(gè)功能是完全可以用代理方法實(shí)現(xiàn)的,即
textFieldDidEndEditing
textFieldDidBeginEditing
但是呢,很不巧,上面?zhèn)zUITextFiled是我自定義的。。。bottom線當(dāng)然也屬于自定義的一部分啦,我可不想每次新創(chuàng)建一個(gè)UITextField對象都要去設(shè)置一下代理方法。又有同學(xué)說了,那你不會(huì)讓你自定義的UITextField自己去實(shí)現(xiàn)代理方法啊,這個(gè)方法好像也可行,但是又很不湊巧,我的ViewController也要實(shí)現(xiàn)它們的代理方法。。。。(!@#¥!@¥)
于是呢,就有了下面一大串實(shí)現(xiàn)這個(gè)功能的代碼了。嗯,點(diǎn)點(diǎn)點(diǎn)是其它被省略的代碼。
class TSUITextField: UITextField {
........
........
override init(frame: CGRect) {
super.init(frame: frame)
.....
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.changeBottomLineColor), name: UITextFieldTextDidBeginEditingNotification, object: self)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.changeBottomLineColor), name: UITextFieldTextDidEndEditingNotification, object: self)
.....
}
......
func changeBottomLineColor() {
if self.editing {
self.bottomLine.backgroundColor = self.bottomLineColorOfSelected
} else {
self.bottomLine.backgroundColor = self.bottomLineColorOfNormal
}
}
func setBottomLineColor(color: UIColor, state: UIControlState){
switch state {
case UIControlState.Normal:
self.bottomLineColorOfNormal = color
case UIControlState.Selected:
self.bottomLineColorOfSelected = color
default:
break
}
}
......
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UITextFieldTextDidBeginEditingNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UITextFieldTextDidEndEditingNotification, object: nil)
}
}
上面的代碼其實(shí)就做了這么幾件事。
- 對自己注冊了UITextFieldTextDidBeginEditingNotification和UITextFieldTextDidEndEditingNotification消息,也可以理解為自己獲得焦點(diǎn)時(shí)發(fā)送消息,失去焦點(diǎn)時(shí)又發(fā)送一次消息。
- 實(shí)現(xiàn)處理方法changeBottomLineColor()。這里面用到了UITextField的可讀屬性editing,當(dāng)失去焦點(diǎn)時(shí)editing為false,獲得焦點(diǎn)時(shí)為true,通過它就可以自由更換顏色了。