I have quite a few controls scattered throughout many table cells in my table, and I was wondering if there's an easier way to dismiss the keyboard without having to loop through all my controls and resigning them all as the first responder. I guess the question is.. How would I get the current first responder to the keyboard?

A caveat to all the below answers. If you perform a segue just after you resign the KB, the KB get's orphaned and cannot not be dismissed. You must dismiss the KB in the textFieldShouldReturn method.
–
gjpcFeb 6 '14 at 19:09

23 Answers
23

This worked perfectly for me, and is certainly preferable to some of the other answers to this question. The docs say it's available in iOS 2.0 and later.
–
antsyawnDec 31 '10 at 1:18

7

As the documentation says: "This method looks at the current view and its subview hierarchy for the text field that is currently the first responder. If it finds one, it asks that text field to resign as first responder. If the force parameter is set to YES, the text field is never even asked; it is forced to resign." - so this is IMO the correct answer to the original question (use-case: I have a form with millions of fields, well - ten... or so, and I need to dismiss the keyboard).
–
joshisJul 19 '11 at 19:34

You can force the currently-editing view to resign its first responder status with [view endEditing:YES]. This hides the keyboard.

Unlike -[UIResponder resignFirstResponder], -[UIView endEditing:] will search through subviews to find the current first responder. So you can send it to your top-level view (e.g. self.view in a UIViewController) and it will do the right thing.

(This answer previously included a couple of other solutions, which also worked but were more complicated than is necessary. I've removed them to avoid confusion.)

But that will only block the component from becoming firstResponder, not remove current firstResponder status from an element.
–
Kendall Helmstetter GelnerApr 13 '09 at 6:29

What I meant in overriding becomeFirstResponder to store the first responder somewhere, so it can be accessed (in this case, resigned) later. The basic problem is that Cocoa Touch does not provide a way to ask a window or view what its first responder is.
–
Nicholas RileyApr 13 '09 at 15:29

3

This is obsolete. The [self.view endEditing:YES]; answer is better.
–
ftvsJun 29 '12 at 4:41

1

This is not obsolete, this answer explain exactly how [UIView endediting:] works. In one of apps I've developed, a search box was added in UINavigationViewController, if you just call [self.view endEditing:YES], as self your view controller, this will not work, instead, I called this method directly in view scope where search box was added, example: [self.mySearchBoxView endEditing:YES].
–
Jan CássioFeb 16 at 1:47

To be honest, I'm not crazy about any of the solutions proposed here. I did find a nice way to use a TapGestureRecognizer that I think gets to the heart of your problem: When you click on anything besides the keyboard, dismiss the keyboard.

In viewDidLoad, register to receive keyboard notifications and create a UITapGestureRecognizer:

Add the keyboard show/hide responders. There you add and remove the TapGestureRecognizer to the UIView that should dismiss the keyboard when tapped. Note: You do not have to add it to all of the sub-views or controls.

The nice thing about this solution is that it only filters for Taps, not swipes. So if you have scrolling content above the keyboard, swipes will still scroll and leave the keyboard displayed. By removing the gesture recognizer after the keyboard is gone, future taps on your view get handled normally.

The UIApplication trick doesn't work (it crashes, at least on the simulator) but you don't need a zero-sized UITextField - just pick any random field and do this with it. NSResponder's becomeFirstResponder is a notification only method, yet UIResponder's isn't (the design is worse, actually).
–
Nicholas RileyApr 13 '09 at 15:50

1

Aha, thanks! It crashes calling it on UIApplication but the zero size UITextField works great, and I don't have to retrieve any of my previous fields.
–
SeventoesApr 21 '09 at 22:59

Why would anyone do this if there is an official, perfectly good and documented method for this?
–
Maciej SwicSep 5 '13 at 7:47

They wouldn't, see most upvoted answer for the better solution. It just was not well known at the time (my answer was from 2009, the other answer came more than a year later in 2010). but I leave it for posterity.
–
Kendall Helmstetter GelnerSep 6 '13 at 20:43

Amendment to my answer to included tempTextField.enabled = NO;. Disabling the text field will prevent UIKeyboardWillShowNotification and UIKeyboardWillHideNotification keyboard notifications from being sent should you rely on these notifications throughout your app.

Quick tip on how to dismiss the keyboard in iOS when a user touches anywhere on the screen outside of the UITextField or keyboard. Considering how much real estate the iOS keyboard can take up, it makes sense to have an easy and intuitive way for your users to dismiss the keyboard.

Jeremy's answer wasn't quite working for me, I think because I had a navigation stack in a tab view with a modal dialog on top of it. I'm using the following right now and it is working for me, but your mileage may vary.

Hmm - why the down-vote? I addressed specific real-world shortcomings in another answer with tested code. I can understand a lack of up-votes, but voting me into negative territory is real discouragement. I still hope the above answer helps someone else.
–
JJ RohrerOct 12 '11 at 3:21

I hate that there's no "global" way to programmatically dismiss the keyboard without using private API calls. Frequently, I have the need to dismiss the keyboard programmatically without knowing what object is the first responder. I've resorted to inspecting the self using the Objective-C runtime API, enumerating through all of its properties, pulling out those which are of type UITextField, and sending them the resignFirstResponder message.

It's not pretty, but the way I resign the firstResponder when I don't know what that the responder is:

Create an UITextField, either in IB or programmatically. Make it Hidden. Link it up to your code if you made it in IB.
Then, when you want to dismiss the keyboard, you switch the responder to the invisible text field, and immediately resign it:

You can recursively iterate through subviews, store an array of all UITextFields, and then loop through them and resign them all.

Not really a great solution, especially if you have a lot of subviews, but for simple apps it should do the trick.

I solved this in a much more complicated, but much more performant way, but using a singleton/manager for the animation engine of my app, and any time a text field became the responder, I would assign assign it to a static which would get swept up (resigned) based on certain other events... its almost impossible for me to explain in a paragraph.

Be creative, it only took me 10 minutes to think through this for my app after I found this question.