There are a hundred and one proposed solutions out there for how to move UITextField
and UITextView
out of the way of the keyboard during editing — usually, it comes down to observing UIKeyboardWillShowNotification
and UIKeyboardWillHideNotification
, or implementing UITextFieldDelegate
delegate methods, and adjusting the frame of the superview, or using UITableView
‘s scrollToRowAtIndexPath:atScrollPosition:animated:
, but all the proposed solutions I’ve found tend to be quite DIY, and have to be implemented for each view controller that needs it.
I thought I’d put together a relatively universal, drop-in solution: UIScrollView
and UITableView
subclasses that handle everything.
When the keyboard is about to appear, the subclass will find the subview that’s about to be edited, and adjust its frame and content offset to make sure that view is visible, with an animation to match the keyboard pop-up. When the keyboard disappears, it restores its prior size.
It should work with basically any setup, either a UITableView-based interface, or one consisting of views placed manually.
For non-UITableViewControllers, use it as-is by dropping the TPKeyboardAvoidingScrollView
source files into your project, popping a UIScrollView
into your view controller’s xib, setting the class to TPKeyboardAvoidingScrollView
, and putting all your controls within that scroll view.
To use it with UITableViewController, pop the TPKeyboardAvoidingTableView
source files in, and just make your UITableView a TPKeyboardAvoidingTableView
in the xib — everything should be taken care of.
You can grab the source files, which includes a sample project, over on the [GitHub project page](https://github.com/michaeltyson/TPKeyboardAvoiding)
Wow! Thanks Michael. You have been posting some really useful blogs. I really appreciate them as a new developer. Thanks!
You’re very welcome Lucas, it’s a pleasure =) Glad to help.
Can you put a project with this example?
Thanks
What about setting this up as a Github project for easy integration as a git submodule?
Your wishes: My command =)
https://github.com/michaeltyson/TPKeyboardAvoiding
Great Job! But i have a Problem, i have included an UIToolBar on the Bottom of my View and after i have clicked on the DONE-Button from the Keyboard, the UIToolBar ist frozen! I cannot click on any UIBarButtonItem on it. On the top of the view, there is an NavigationBar and it is not frozen and works very well. Any idea whats wrong?
Not from your description, I’m afraid. The sample project has a UIToolBar at the bottom, and it works fine, so I’m not sure how to replicate it. If you could provide a sample project somewhere, it might be instructive.
TPKeyboardAvoidingTableView works greatly in portrait mode, but it fails in landscape mode, please take some time to correct it.
Thank you for your blog.
Good point – That should do it.
Thanks for sharing us your Knowledge. Have you fixed the problem with the landscape mode?
Yep – it should work fine now.
Great! Thank you for your work! :-)
Have a nice day!
Hi
Thanks for the very nice tutorial. I have a UITableview with custom UITableviewcells in it holding multiple UITextfields. In my case, the fields that are below the keyboard move way up and the other textfields work nice.
Thanks
Thanks for the work. But does it work with UITextView?
Auto-reply: YES :)
Thanks for this sample code! Way better than my solution U rock!! Thanks again
You’re very welcome!
This is great tutorial.But i am having a problem .Everything works properly the scrollview ,textfield but the keyboard does not resigns ,it remains there itself after completion of its work i.e . typing
Hi Raji; Are you calling resignFirstResponder on the text field when you want to hide the keyboard?
Michael — very nicely done. Thank you 100000 for sharing this! I’ve spent many hours working on this but your solution is 1000x better. I am having some trouble with the TableView working on iOS4.3/xcode 4 (doesn’t scroll), but for my current purpose, I only need the TextFields. Still, I thought’ I’d point the issue out.
i am using tableView with textFields on it..as like u did in sample proj But i hav an issue with the textFields .. can u make keyBoard custom type by Adding the prev and next buttons on it so user no need to scroll to below to enter data in txtfields which covered by keyBoard.. right now if i want to enter data on all text fields in ur example table View ,i hav to scroll table cells ..so i want to add prev and next buttons on keyboard …
Thanks again for ur code..
You’ll need to implement that yourself.
in my project there is a toolbar on the top and all the fields below it. I am using your scrollview codes. all works well except when the keyboard hides. when the keyboard starts hiding, the scrollview scrolls down over the toolbar instead of scrolling under toolbar.
I am still new to objective c. Could you please let me know how I should adjust the code to make scrollview scrolls down under toolbar instead of over it?
Thanks
On the top of the view, there is an NavigationBar and it is not frozen and works very well.
I am using your scrollview codes. all works well except when the keyboard hides. when the keyboard starts hiding, the scrollview scrolls down over the toolbar instead of scrolling under toolbar.
Hello – does the latest version on github (with the changes I merged in earlier today) still have this issue?
I had major problems with this because i had UIViews on top of my scroll view which was throwing the calculations way off. However, I found this post where Christian Schlensker did a fork on the github project that MICHAEL TYSON has put up. This fixed EVERYthing. This is the BEST solution EVER for Apples stupid keyboard management craziness. Thanks to both of you for sharing!
http://stackoverflow.com/questions/6239697/scrollviews-position-jumps-during-animation-when-contentoffset-has-value
Hi Michael, many thanks for your very interesting code ! I just found that UITableView class already handle properly the keyboard (at least in 4.3, didn’t test with other versions). I commented the setup method and I have the same behavior.
regards john
Good lord, you’re right! Apple must’ve quietly added support. Good to know!
Hi Michael, this has saved me a lot of work and is much appreciated. I have one problem with a UITextView, when the keyboard is hidden and I enter the textview everything scrolls fine. If i then enter a textfield above and then go back to the textview while the keyboard is open the textview remains behind the keyboard.
Any pointers as to what i am doing wrong ?
Regards
Rob
Hey Rob,
Hmm, interesting – I’d love to see a screen capture of this problem, as I’m having trouble visualising it (QuickTime Player will do it).
Michael:
Very good code, it works almost perfectly for me. I have an iPad app that can work in both portrait and landscape mode, and I put all my views into the TPKeyboardAvoidingScrollView. It works great in portrait mode, but when I switch to landscape mode, there is some extra dead space added to the bottom of the view. I put together a simple test app to illustrate the problem:
http://www.dosomethinghere.com/downloads/KBTest.zip
When you rotate to landscape and tap on the text view on the bottom of the view, it is readily apparent that the view has dead space in it.
Could you take a look at it and see if I am doing something wrong, or if there is some kind of miscalculation going on in your class? And is this because the UIKeyboardFrameEndUserInfoKey frame has the keyboard height in size.width when you are in landscape mode?
Thanks.
BP
I logged the issue with the iPad & landscape mode with the ScrollView. Other than that, this is totally, insanely great. Why the crap can’t Apple just make this the way it all works, automatically?
Fantastic work. Any ideas on the landscape mode issue with the ScrollView?
Thanks!
Thanks heaps, John – and sorry about the delay! I’ve been flat-out working on Loopy. I haven’t forgotten you, though – I’ll take a look at this soon.
Awesome. I bought a copy of Loopy to encourage the bugfix! :)
That’s very kind ;-)
Any update on the iPad landscape issue?
Hey Michael , Thanx for this code. Its working for most of the time but fails sometimes. I have two views. These two views again contains some textfields and textViews. When keyboard appears it scrolls the scroll View but when keyboard disappers , the scroll view does not scroll back to the original location.
Do you have any idea , whats exactly going wrong . . .?
Thanks in advance !! Bharat
The same thing happens to my project. Both in portrait and in landscape, when the keyboard disappear doesn’t return to the original location. In portrait mode about 10 px misses, but in landscape mode the space is bigger: about 50 px.. Any hints??
Hi Michael, your solutions works great and thanks for it. Just wanted to ask you if you could do a walkthrough of your solution so that I could understand whats going on inside.
Thanks.
Wow! Thank you so much! I was really struggling with this, and being somewhat new at iOS Development, all of the solutions I was finding for adjusting the scrollview were very confusing. This just saved me so much frustration! I’ll be putting credit in my app because you definitely deserve it!
Cheers, Lee, glad it was useful!
You sir, are a lifesaver.
Thanks for such a useful code… but having one problem. When keyboard hides the scroll does not work !!! any idea ???
Thanks for the code it’s very usefull, the setup works fine in very rotation, PERFECT. I have implement a button with no functions or delegates the same as the example , but when i click on the button the view scrolls down with the dimension of the keyboard and the keyboard is dismissed. any suggestions are welcome. RNB
Brilliant! I have searched high and wide for a solution that actually works with the iPad in both portrait and landscape modes. And here it is. Kudos to you sir.
Its works like a charm. You rock man. Love you :D
Sweet! ;-)
Great solution! After spending hours on trying to fix this problem even a newbie like me could follow and implement! Thanks again.
This is amazing! So easy to implement, but I’m just having one little problem and I probably haven’t linked something up properly.
When we finally “resignFirstResponder” from the UITextField, my scrollview doesn’t move back to the normal offset.
Your sample project does this beautifully, but I can’t see how. Any idea what I’m missing?
Michael,
I had to post a comment. Your class is fantastic!! You just saved me about a day’s work. I’m starting a new project (new to iPad) development and I’ll be able to plug this class into all of my views. Outstanding job!!!
Thanks for posting this!!
Bob
You sir are a genius! Thank you so much. It’s through the efforts of people like you that Apple’s SDKs become usable!