To my understanding the object
parameter of the addObserver
method is the object you want to receive notifications from. Most of the time I see it as nil
(I assume this is because notifications of the specified type are wanted from all objects). In my particular case I have a text field at the top of the screen and at the bottom of the screen and I want the view to move up only when the user taps the bottom text field, not the top one. So I call the following method in viewWillAppear
func subscribeToKeyboardNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: self.bottomTextField)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: self.bottomTextField)
}
the keyboardWillShow:
and keyboardWillHide:
selectors call methods that do the repositioning of the view's frame. I tried leaving the object
parameter to be nil
but that would receive notifications from both text fields. I tried setting the object
parameter to self.bottomTextField
(as seen above) but that doesn't receive notifications from either text field. My question is twofold. First, am I understanding the addObserver
method correctly (especially the object
parameter) and second, why is it not registering notifications from self.bottomTextField
. Thanks!
Solution: I know this isn't the solution to the exact question I was asking but what I did in the end to make the view move up when only clicking on the bottom text field was the following:
func subscribeToKeyboardNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}
and then in the keyboardWillShow:
method I have:
func keyboardWillShow(notification: NSNotification) {
if bottomTextField.editing { // only reset frame's origin if editing from the bottomTextField
view.frame.origin.y -= getKeyboardHeight(notification)
}
}
Hopefully that helps!
Yes, you've got it. Specifying
nil
means that you'll get the notification regardless of which object sent it; providing a pointer to an object means that you're observing the notification from that specific object.You're observing the wrong notification.
UITextField
never sendsUIKeyboardWillShowNotification
-- that's a notification that comes from the window. If you specifynil
for theobject
parameter, then you get the notification from any object that sends it, including the window. But when you specified the text field as the object parameter, you didn't get any notification at all because text fields don't send that notification. You should instead observeUITextFieldTextDidBeginEditingNotification
andUITextFieldTextDidEndEditingNotification
, which are the notifications thatUITextField
sends.Because on your code, the
self.bottomTextField
did not trigger the notification, but the keyboard, when u pass the sender to the object param, only notifications sent by this sender are delivered to the observer, if u usenil
mean it will be receive by all sourceTo fix your problem, u have to convert your textfield point to get the textfield or use textfield delegate such as
textFieldShouldBeginEditing
andtextFieldShouldEndEditing
which have textfield param with itThe category to get the current responder textfield: