I know that I need to tell my UITextField to resign first responder when I want to dismis the keyboard, but I'm not sure how to know when the user has pressed the "Done" key on the keyboard. Is there a notification I can watch for?
-
2[self.view endEditing:YES]; in touches began delegate is the best solution – Zar E Ahmer Nov 15 '14 at 06:51
22 Answers
I set the delegate of the UITextField
to my ViewController
class.
In that class I implemented this method as following:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
-
See the example above... wire that using IntefaceBuilder to the action on whatever you're using as your controller... whenever the user dismisses the text entry system (presses done), this will be invoked... – Jason Coco Nov 08 '08 at 04:27
-
2Either of these will work - the text field sends its action when the user hits the Return ("Done", whatever) key, and also sends its delegate -textFieldShouldReturn:. – Noah Witherspoon Nov 08 '08 at 05:13
-
BTW - this also works for a UISearchBar. For example, my code I had a member IBOutlet searchBarTusb; When my 'return key' (UIReturnKeySearch) was clicked, -(void) searchBarSearchButtonClicked:, I put the statement [searchBarTusb resignFirstResponder]; Also note, the 'return key' was set in the NIB using Interface Builder. – mobibob Jan 04 '10 at 05:24
-
-
@IulianOnofrei The default behavior of the return button is to add a line return and keep the keyboard onscreen. By returning `NO` you avoid adding a line return to the text. – kubi Feb 20 '19 at 23:53
-
-
This no longer works. You have to dismiss the keyboard after a delay. `func textFieldShouldClear(_ textField: UITextField) -> Bool { DispatchQueue.main.async { self.resignFirstResponder() } return true } ` – alekop Aug 22 '19 at 19:29
If you connect the DidEndOnExit event of the text field to an action (IBAction) in InterfaceBuilder, it will be messaged when the user dismisses the keyboard (with the return key) and the sender will be a reference to the UITextField that fired the event.
For example:
-(IBAction)userDoneEnteringText:(id)sender
{
UITextField theField = (UITextField*)sender;
// do whatever you want with this text field
}
Then, in InterfaceBuilder, link the DidEndOnExit event of the text field to this action on your controller (or whatever you're using to link events from the UI). Whenever the user enters text and dismisses the text field, the controller will be sent this message.

- 23,293
- 19
- 66
- 73

- 77,985
- 20
- 184
- 180
-
The only event that seems like it might work is textFieldDidEndEditing, which states it's only sent after the UITextField resigns first responder status. How do I know when I need to resign first responder status? – kubi Nov 08 '08 at 04:04
-
I'm sorry about the terminology... it's not an actual notification (event)... I'm going to edit my answer with a quick example and explanation, so see that :) – Jason Coco Nov 08 '08 at 04:22
-
1To clarify this answer, the textField sends the "Did End On Exit" event when you hit the return key, so that's the one you need to link to your controller. I think this method is easier than the one I outlined above. – kubi Apr 22 '09 at 20:49
-
2could you edit this answer so that it mentions WHICH event to wire, please? This is obviously nicer than setting the delegate. – Dan Rosenstark Dec 24 '10 at 20:52
-
1Want to upvote this answer, but can't until it mentions the DidEndOnExit event. Someone with edit privileges please make the change if the OP won't? – James Hart Apr 21 '11 at 15:22
You can also create a method in your controller
-(IBAction)editingEnded:(id)sender{
[sender resignFirstResponder];
}
and then in Connection Inspector in IB connect Event "Did End On Exit" to it.

- 331
- 3
- 2
-
1This is almost incorrect, or at least it misses the point. By subscribing to the `DidEndOnExit` event, you do not need to call `resignFirstResponder`. You can test this by putting a symbolic breakpoint on `[UIResponder resignFirstResponder]`. Note that even if if you don't call resignFirstResponder, it still gets called by the system. This is explained in Matt Neuburg's excellent book(s): http://www.apeth.com/iOSBook/ch23.html#_text_field_delegate_and_control_event_messages – Chris Conover Apr 24 '15 at 18:54
kubi, thanks. Your code worked. Just to be explicit (for newbies like) as you say you have to set the UITextField
's delegate
to be equal to the ViewController in which the text field resides. You can do this wherever you please. I chose the viewDidLoad
method.
- (void)viewDidLoad
{
// sets the textField delegates to equal this viewController ... this allows for the keyboard to disappear after pressing done
daTextField.delegate = self;
}

- 415,655
- 72
- 787
- 1,044
-
If you added text field to your storyboard or NIB, you can set the text field's `delegate` there, too. You don't have to do this programmatically, as demonstrated above. Either approach works fine. – Rob Jan 18 '13 at 13:21
Here is a trick for getting automatic keyboard dismissal behavior with no code at all. In the nib, edit the First Responder proxy object in the Identity inspector, adding a new first responder action; let's call it dummy:
. Now hook the Did End on Exit event of the text field to the dummy:
action of the First Responder proxy object. That's it! Since the text field's Did End on Exit event now has an action–target pair, the text field automatically dismisses its keyboard when the user taps Return; and since there is no penalty for not finding a handler for a message sent up the responder chain, the app doesn't crash even though there is no implementation of dummy:
anywhere.

- 515,959
- 87
- 875
- 1,141
-
@matt I discovered that IF I add an unwind segue AND connect the didEndOnExit event THEN the unwind segue will be triggered upon pressing Return. Without the event connection the segue is not triggered. Great but Huh? Any remarks? BTW: I have your Swift (finished) and iOS10 (on chap 6) books. They have helped me tremendously! – Verticon Nov 13 '17 at 15:28
-
@Verticon the question and answer has nothing to do with segues, so I don't understand the issue... :( this is purely about keyboard dismissal – matt Nov 13 '17 at 16:10
-
@matt Sorry, man. I was piggy backing because 1) I came upon this thread while I was dealing with how to handle the UITextField's return key; and 2) it was a chance to interact with you (thx for da books). There is no "issue". Just a lack of understanding on my part about why/how it works the way it does. – Verticon Nov 13 '17 at 20:20
-
@Verticon I apologize for not being able to help. Feel free to formulate a new question with more info (demo project?) and blip me, if I can be useful. – matt Nov 13 '17 at 20:43
-
@matt Thanks https://stackoverflow.com/questions/47289747/triggering-a-uitextfield-unwind-segue-by-pressing-return-why-how-does-this-work – Verticon Nov 14 '17 at 15:42
In Swift you can write an IBAction in the Controller and set the Did End On Exit event of the text field to that action
@IBAction func returnPressed(sender: UITextField) {
self.view.endEditing(true)
}

- 560
- 4
- 12
Just add
[textField endEditing:YES];
where you want to disable keyboard and display the picker view.

- 4,106
- 36
- 54

- 111
- 1
- 2
Swift 4.2
and It will work 100%
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.textField.delegate = self
}
// hide key board when the user touches outside keyboard
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
// user presses return key
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}

- 3,975
- 6
- 27
- 43

- 188
- 2
- 11
-
1I appreciated the fact that this answer also taught me how to dismiss the keyboard when the user touches outside it. – Carl Smith Dec 27 '20 at 22:08
You can also use
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.yourTextField resignFirstResponder];
}
Best one if You have many Uitextfields :
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}

- 1,978
- 1
- 17
- 28
Here's what I had to do to get it to work, and I think is necessary for anyone with a Number Pad for a keyboard (or any other ones without a done button:
- I changed the UIView in the ViewController to a UIControl.
I created a function called
-(IBAction)backgroundIsTapped:(id)sender
This was also defined in the .h file.
After this, I linked to to the 'touch down' bit for the ViewController in Interface Builder.
In the 'background is tapped' function, I put this:
[answerField resignFirstResponder];
Just remember to change 'answerField' to the name of the UITextField you want to remove the keyboard from (obviously make sure your UITextField is defined like below:)
IBOutlet UITextField * <nameoftextfieldhere>;
I know this topic probably died a long time ago... but I'm hoping this will help someone, somewhere!

- 21
- 1
You will notice that the method "textFieldShouldReturn" provides the text-field object that has hit the DONE key. If you set the TAG you can switch on that text field. Or you can track and compare the object's pointer with some member value stored by its creator.
My approach is like this for a self-study:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSLog(@"%s", __FUNCTION__);
bool fDidResign = [textField resignFirstResponder];
NSLog(@"%s: did %resign the keyboard", __FUNCTION__, fDidResign ? @"" : @"not ");
return fDidResign;
}
Meanwhile, I put the "validation" test that denies the resignation follows. It is only for illustration, so if the user types NO! into the field, it will not dismiss. The behavior was as I wanted, but the sequence of output was not as I expected.
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
NSLog(@"%s", __FUNCTION__);
if( [[textField text] isEqualToString:@"NO!"] ) {
NSLog(@"%@", textField.text);
return NO;
} else {
return YES;
}
}
Following is my NSLog output for this denial followed by the acceptance. You will notice that I am returning the result of the resign, but I expected it to return FALSE to me to report back to the caller?! Other than that, it has the necessary behavior.
13.313 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldReturn:] 13.320 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldEndEditing:] 13.327 StudyKbd[109:207] NO! 13.333 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldReturn:]: did resign the keyboard 59.891 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldReturn:] 59.897 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldEndEditing:] 59.917 StudyKbd[109:207] -[StudyKbdViewController doneEditText]: NO 59.928 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldReturn:]: did resign the keyboard
-
1can u explain ..if i return NO or YES in both case same things happen so what the need of returning yes in textFieldShouldReturn delegate method – K. Jaiswal Apr 06 '13 at 08:00
Here is a quite clean way to end edition with the Return Key or a touch in the background.
In Interface builder, embed your fields in a view of class UIFormView
What does this class :
- Automatically attach itself as fields delegate ( Either awaked from nib, or added manually )
- Keep a reference on the current edited field
- Dismiss the keyboard on return or touch in the background
Here is the code :
Interface
#import <UIKit/UIKit.h>
@interface UIFormView : UIView<UITextFieldDelegate>
-(BOOL)textFieldValueIsValid:(UITextField*)textField;
-(void)endEdit;
@end
Implementation
#import "UIFormView.h"
@implementation UIFormView
{
UITextField* currentEditingTextField;
}
// Automatically register fields
-(void)addSubview:(UIView *)view
{
[super addSubview:view];
if ([view isKindOfClass:[UITextField class]]) {
if ( ![(UITextField*)view delegate] ) [(UITextField*)view setDelegate:self];
}
}
// UITextField Protocol
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
currentEditingTextField = textField;
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
currentEditingTextField = NULL;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self endEdit];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if ([self textFieldValueIsValid:textField]) {
[self endEdit];
return YES;
} else {
return NO;
}
}
// Own functions
-(void)endEdit
{
if (currentEditingTextField) {
[currentEditingTextField endEditing:YES];
currentEditingTextField = NULL;
}
}
// Override this in your subclass to handle eventual values that may prevent validation.
-(BOOL)textFieldValueIsValid:(UITextField*)textField
{
return YES;
}
@end
By subclassing the form and overriding the
textFieldValueIsValid:
method, you can avoid end of edition if the value is not correct for the given field.If a field has a delegate set in Interface Builder, then the form does not change it. I don't see many reasons to set a different delegate to a particular field, but why not…
There is many ways to improve this form view class - Attach a delegate, do some layout, handle when the keyboards covers a field ( using the currentEditingTextField frame ), automatically start edition for the next field, ...
I personally keep it in my framework, and always subclass it to add features, it is quite often useful "as-is".
I hope it will helps. Cheers all

- 2,607
- 24
- 23
-
1Helpful class. One small point, you shouldn't prefix your own classes with "UI". In objective-c you should use your own prefix ("TL"?), in Swift, don't use anything. – kubi Sep 10 '15 at 15:25
-
Thanks @kubi. That's right. It is MF in my framework, like MooseFactory ;) – Moose Sep 11 '15 at 01:25
if you want all editing of in a UIViewController you can use.
[[self view]endEditing:YES];
and if you want dismiss a perticular UITextField keyboard hide then use.
1.add delegate in your viewcontroller.h
<UITextFieldDelegate>
make delegation unable to your textfield .
self.yourTextField.delegate = self;
add this method in to your viewcontroller.
-(BOOL)textFieldShouldEndEditing:(UITextField *)textField{ [textField resignFirstResponder]; return YES;}

- 1,095
- 16
- 20
Anyone looking for Swift 3
1) Make sure your UITextField's Delegate is wired to your ViewController in the Storyboard
2) Implement UITextFieldDelegate in your ViewController.Swift file (e.g class ViewController: UIViewController, UITextFieldDelegate { )
3) Use the delegate method below
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return false }

- 5,001
- 14
- 58
- 117
Programmatically set the delegate of the UITextField in swift 3
Implement UITextFieldDelegate in your ViewController.Swift file (e.g class ViewController: UIViewController, UITextFieldDelegate { )
lazy var firstNameTF: UITextField = {
let firstname = UITextField()
firstname.placeholder = "FirstName"
firstname.frame = CGRect(x:38, y: 100, width: 244, height: 30)
firstname.textAlignment = .center
firstname.borderStyle = UITextBorderStyle.roundedRect
firstname.keyboardType = UIKeyboardType.default
firstname.delegate = self
return firstname
}()
lazy var lastNameTF: UITextField = {
let lastname = UITextField()
lastname.placeholder = "LastName"
lastname.frame = CGRect(x:38, y: 150, width: 244, height: 30)
lastname.textAlignment = .center
lastname.borderStyle = UITextBorderStyle.roundedRect
lastname.keyboardType = UIKeyboardType.default
lastname.delegate = self
return lastname
}()
lazy var emailIdTF: UITextField = {
let emailid = UITextField()
emailid.placeholder = "EmailId"
emailid.frame = CGRect(x:38, y: 200, width: 244, height: 30)
emailid.textAlignment = .center
emailid.borderStyle = UITextBorderStyle.roundedRect
emailid.keyboardType = UIKeyboardType.default
emailid.delegate = self
return emailid
}()
// Mark:- handling delegate textField..
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
view.endEditing(true)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == firstNameTF {
lastNameTF.becomeFirstResponder()
}
else if textField == lastNameTF {
emailIdTF.becomeFirstResponder()
}
else {
view.emailIdTF(true)
}
return true
}

- 5,695
- 2
- 8
- 17
Create a function hidekeyboard and link it to the textfield in the .xib file and select DidEndOnExit
-(IBAction)Hidekeyboard
{
textfield_name.resignFirstResponder;
}

- 35
- 1
- 9
If you have created the view using Interface Builder, Use the following Just create a method,
-(IBAction)dismissKeyboard:(id)sender
{
[sender resignFirstResponder];
}
Just right click the text field in the view , and set the event as Did End on Exit, and wire it to the method "dismissKeyboard".
The best guide for beginners is "Head First iPhone and iPad Development, 2nd Edition"
try this
- (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
{
if ([text isEqualToString:@"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}

- 7,755
- 12
- 66
- 130
//====================================================
// textFieldShouldReturn:
//====================================================
-(BOOL) textFieldShouldReturn:(UITextField*) textField {
[textField resignFirstResponder];
if(textField.returnKeyType != UIReturnKeyDone){
[[textField.superview viewWithTag: self.nextTextField] becomeFirstResponder];
}
return YES;
}

- 1
This is how I dismiss the keyboard in Swift 4.2 and it works for me:
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action:
#selector(dismissKeyboard))
view.addGestureRecognizer(tap)
}
@objc func dismissKeyboard (_ sender: UITapGestureRecognizer) {
numberField.resignFirstResponder()
}

- 976
- 14
- 16
Swift 3, iOS 9+
@IBAction private func noteFieldDidEndOnExit(_ sender: UITextField) {}
UPD: It still works fine for me. I think guy that devoted this answer just didn't understand that he needs to bind this action to the UITextField at the storyboard.

- 970
- 12
- 20
textField.returnKeyType = UIReturnKeyDone;

- 15,750
- 31
- 68
- 83

- 2,070
- 2
- 18
- 18