Blog

A drop-in universal solution for moving text fields out of the way of the keyboard

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.

201104121152.jpgFor 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

, , , . Bookmark the permalink. Both comments and trackbacks are currently closed.

52 Comments

  1. Lucas Goossen
    Posted April 12, 2011 at 3:51 pm | Permalink

    Wow! Thanks Michael. You have been posting some really useful blogs. I really appreciate them as a new developer. Thanks!

    • Posted April 12, 2011 at 3:57 pm | Permalink

      You’re very welcome Lucas, it’s a pleasure =) Glad to help.

  2. mooscos
    Posted April 14, 2011 at 8:24 am | Permalink

    Can you put a project with this example?

    Thanks

  3. Posted April 14, 2011 at 3:08 pm | Permalink

    What about setting this up as a Github project for easy integration as a git submodule?

  4. Posted April 14, 2011 at 4:12 pm | Permalink
  5. Marius Deutz
    Posted April 20, 2011 at 9:38 pm | Permalink

    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?

    • Posted April 22, 2011 at 3:59 pm | Permalink

      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.

  6. iKyoto
    Posted April 22, 2011 at 11:47 am | Permalink

    TPKeyboardAvoidingTableView works greatly in portrait mode, but it fails in landscape mode, please take some time to correct it.

    Thank you for your blog.

    • Posted April 22, 2011 at 3:57 pm | Permalink

      Good point – That should do it.

      • Frank
        Posted April 25, 2011 at 10:47 am | Permalink

        Thanks for sharing us your Knowledge. Have you fixed the problem with the landscape mode?

        • Posted April 25, 2011 at 11:15 am | Permalink

          Yep – it should work fine now.

          • Frank
            Posted April 27, 2011 at 5:10 pm | Permalink

            Great! Thank you for your work! :-)

            Have a nice day!

        • moniviki
          Posted May 19, 2011 at 11:49 am | Permalink

          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

  7. Billiot Clément
    Posted April 27, 2011 at 11:35 pm | Permalink

    Thanks for the work. But does it work with UITextView?

    • Billiot Clément
      Posted April 27, 2011 at 11:39 pm | Permalink

      Auto-reply: YES :)

  8. Posted May 5, 2011 at 6:05 pm | Permalink

    Thanks for this sample code! Way better than my solution U rock!! Thanks again

  9. Raji Nair
    Posted May 6, 2011 at 6:26 am | Permalink

    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

    • Posted May 6, 2011 at 1:38 pm | Permalink

      Hi Raji; Are you calling resignFirstResponder on the text field when you want to hide the keyboard?

  10. Posted May 12, 2011 at 4:14 pm | Permalink

    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.

  11. lak
    Posted June 3, 2011 at 10:18 pm | Permalink

    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..

  12. peili cui
    Posted July 19, 2011 at 5:45 am | Permalink

    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

  13. Posted July 26, 2011 at 8:55 pm | Permalink

    On the top of the view, there is an NavigationBar and it is not frozen and works very well.

  14. Posted August 11, 2011 at 10:45 pm | Permalink

    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.

    • Posted August 13, 2011 at 12:41 pm | Permalink

      Hello – does the latest version on github (with the changes I merged in earlier today) still have this issue?

  15. Ross Arroyo
    Posted August 13, 2011 at 5:13 am | Permalink

    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

  16. John Boydon
    Posted August 16, 2011 at 10:54 am | Permalink

    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

    • Posted August 19, 2011 at 2:04 pm | Permalink

      Good lord, you’re right! Apple must’ve quietly added support. Good to know!

  17. Rob Lindsay
    Posted September 1, 2011 at 9:45 pm | Permalink

    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

    • Posted September 5, 2011 at 12:47 pm | Permalink

      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).

  18. Posted September 14, 2011 at 6:40 pm | Permalink

    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

    • John Watson
      Posted September 28, 2011 at 4:26 am | Permalink

      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!

      • Posted October 10, 2011 at 4:53 pm | Permalink

        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.

        • John Watson
          Posted October 15, 2011 at 6:39 pm | Permalink

          Awesome. I bought a copy of Loopy to encourage the bugfix! :)

          • Posted October 18, 2011 at 12:33 pm | Permalink

            That’s very kind ;-)

          • John Watson
            Posted November 23, 2011 at 3:55 pm | Permalink

            Any update on the iPad landscape issue?

  19. Posted October 6, 2011 at 9:57 am | Permalink

    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

    • Miwi
      Posted July 4, 2012 at 2:45 pm | Permalink

      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??

  20. Nayaab
    Posted October 22, 2011 at 9:36 am | Permalink

    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.

  21. Posted November 20, 2011 at 4:01 pm | Permalink

    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!

  22. John
    Posted December 3, 2011 at 1:00 pm | Permalink

    You sir, are a lifesaver.

  23. Mogs
    Posted December 10, 2011 at 9:04 am | Permalink

    Thanks for such a useful code… but having one problem. When keyboard hides the scroll does not work !!! any idea ???

  24. RNB-IT
    Posted December 15, 2011 at 10:10 pm | Permalink

    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

  25. Andrew
    Posted January 5, 2012 at 11:56 am | Permalink

    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.

  26. Mr.Kela
    Posted January 11, 2012 at 11:00 pm | Permalink

    Its works like a charm. You rock man. Love you :D

  27. Kathy
    Posted January 15, 2012 at 7:03 pm | Permalink

    Great solution! After spending hours on trying to fix this problem even a newbie like me could follow and implement! Thanks again.

  28. whiskit
    Posted January 17, 2012 at 2:39 pm | Permalink

    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?

  29. Bob Hill
    Posted February 8, 2012 at 8:50 pm | Permalink

    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

  30. Roger
    Posted February 10, 2012 at 12:47 am | Permalink

    You sir are a genius! Thank you so much. It’s through the efforts of people like you that Apple’s SDKs become usable!