I have an application in which I have to scroll up in case of the keyboard showing. to get the keyboard size, I'm registering the UIKeyboardWillShowNotification event like so:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window]
This does work, the problem is, it is being called after the textFieldDidBeginEditing was called. So, I can't get the actual keyboard size, but only after the field is already in edit mode, which defeats the whole purpose of registering this event on the first place. I'm sure I've called the UIKeyboardWillShowNotification and not the UIKeyboardDidShowNotification, although switching these two yield the same results: first call was made to the delegate method and only then to the notification method. Any idea on how to turn this around? Currently I'm hard coding the size, which is very bad practice...
According to the Apple documentation UIKeyboardWillShowNotification is called just before the keyboard will be shown, while UITextFieldDidBeginEditing is called just after the text field becomes first responder. The process to show the keyboard is started after the text field becomes first responder, and only if the keyboard is not already shown. This means UIKeyboardWillShowNotification will be called after UITextFieldDidBeginEditing. So UITextFieldDidBeginEditing is not called prematurely.
If you just want to scroll up so the text field won't be hidden under the keyboard, you can just set the content offset of the scroll view to the y-origin of the text field in UITextFieldShouldBeginEditing or UITextFieldDidBeginEditing.
Here is a base class I have written for this use exactly.It is a subclass of
UIViewController
Whenever I want to implement such behaviour I just make my view controller a sub class of this base class.BTW - You are right.
textFieldDidBeginEditing
is called after keyboard shows up which is why you want to scroll up in the call backs method of the keyboard as described in my class.Also please note that for this to work you need to embed your entire view in a Scroll View and connect the IBOutlet of the scroll view to it.
If you are not using story board remove the IBOutlet part and embed your view in a scroll view and make the connection in code.
After this said here is the code:
Header File
Implementation File
May I suggest a GitHub repository
https://github.com/hackiftekhar/IQKeyboardManager
I opened a new project in XCode 5, added a
UITextField
to theViewController
and connected its delegate.This is my only code:
Here's the log output:
Portraid:
Landscape:
Edit:
Regarding
textFieldDidBeginEditing
being called beforename:UIKeyboardWillShowNotification
, I don't really understand why there's a difference if the textField is in edit mode or not but there are a few ways to solve this.saving a reference to textField from textFieldShouldBeginEditing and use it inside myNotificationMethod if in did textFieldShouldBeginEditing was triggered.
Playing around with
UIResponder
like so:in
textFieldDidBeginEditing
-> Save a reference to theUIResponder
and change theUIResponder
to a temp irrelevant one. inmyNotificationMethod
do what ever you want to do to the textField (that is not in edit mode \ first responder), when you are done make it your mainUIResponder
.Old question, but I ran into the same issue today. I have built a little "dirty" workaround that does not force me to hardcode the keyboard size. I simply did the following in viewDidAppear (attention - Swift):
This triggers the UIKeyboardWillShowNotification and you can get the keyboard size from the notification and store it in a property. Hope this helps someone, it worked in my case.