264

I am using UITextfied while clicking on textfied keyboard appear but when i pressed the return key, keyboard is not disappearing. I used the following code:

func textFieldShouldReturn(textField: UITextField!) -> Bool // called when 'return' key pressed. return NO to ignore.
{
    return true;
}

the method resignfirstresponder is not getting in function.

GabrieleMartini
  • 1,665
  • 2
  • 19
  • 26
Ashwinkumar Mangrulkar
  • 2,956
  • 3
  • 15
  • 17

20 Answers20

458

You can make the app dismiss the keyboard using the following function

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    self.view.endEditing(true)
    return false
}

Here is a full example to better illustrate that:

//
//  ViewController.swift
//
//

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var myTextField : UITextField

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.myTextField.delegate = self
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        self.view.endEditing(true)
        return false
    }
}

Code source: http://www.snip2code.com/Snippet/85930/swift-delegate-sample

Papershine
  • 4,995
  • 2
  • 24
  • 48
rsc
  • 10,348
  • 5
  • 39
  • 36
  • 23
    I was missing "self.myTextField.delegate = self;" Thank you! – tylerlindell Dec 14 '14 at 01:21
  • 5
    I was missing the `UITextFieldDelegate`! – Cesare Apr 26 '15 at 13:29
  • @RSC can you explain the line `self.myTextField.delegate = self` to me. it works but I don't really know whats happening here ( tried googling , with out any success) – jonnie Apr 26 '15 at 18:10
  • https://developer.apple.com/library/mac/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html – rsc Apr 27 '15 at 18:07
  • 1
    @kommradHomer, without doubt there is something else that is making your keyboard not to show. If you want, put your code on pastebin and paste the link here for me to see it. – rsc Oct 22 '15 at 17:29
  • 1
    @RSC you were most probably right. i'm a 2 days newbie on ios , so somehow got rid of my problem and everything worked as you suggested :) – kommradHomer Oct 23 '15 at 06:40
  • what is the difference between return true or false? I tried both and both is working same? – kuzdu Mar 31 '16 at 09:29
  • 1
    So work for me (swift 3): `func textFieldShouldReturn(textField: UITextField) -> Bool {` change to `func textFieldShouldReturn(_ textField: UITextField) -> Bool {` – sea-kg Dec 30 '16 at 08:05
  • Why do I have to change the type of FirstViewController to UIViewController, UITextFieldDelegate? I get that without that I'll get an error. But why is that? – PeterPan Apr 14 '17 at 16:54
  • When you add the ", UITextFieldDelegate", you are basically saying that your ViewController is going to conform with the UITextFieldDelegate protocols and therefore can be treated as a Delegate for the TextField functions (in this case, to the "textFieldShouldReturn" function). – rsc Apr 15 '17 at 20:55
  • this is a nice answer but putting unnecessary self is not recomended – SHAH MD IMRAN HOSSAIN Mar 24 '20 at 05:34
145

The return true part of this only tells the text field whether or not it is allowed to return.
You have to manually tell the text field to dismiss the keyboard (or what ever its first responder is), and this is done with resignFirstResponder(), like so:

// Called on 'Return' pressed. Return false to ignore.

func textFieldShouldReturn(_ textField: UITextField) -> Bool { 
    textField.resignFirstResponder()
    return true
}
Mick MacCallum
  • 129,200
  • 40
  • 280
  • 281
  • 2
    thanks...in my case "resignFirstResponder()" method was not getting automatically and i thought that it was not supporting but while writing manually its working fine..thanks that's i m looking for. – Ashwinkumar Mangrulkar Jun 12 '14 at 09:49
  • @AshwinMangrulkar you can expect that in beta version of Xcode 6 auto completion feature could be handicapped. – Paweł Brewczynski Jul 17 '14 at 07:17
  • @0x7fffffff could you explain what "resignFirstResponder" means ? I've read the documentation for UIresponder and I don't fully understand what is it. It seems that it's vague method used to "loose focus on particular UI element" that is custom implemented in UITextField. – Paweł Brewczynski Jul 17 '14 at 07:26
  • 1
    and of course the semicolon after "true" isn't required anymore – 36 By Design Apr 04 '16 at 16:07
  • 2
    isn't it a requirement that your viewController conforms to `UITextFieldDelegate`? – mfaani Sep 21 '16 at 17:15
  • 1
    instead of self.view.endEditing() this answer is appropriate and the correct approach – saigen Feb 12 '18 at 11:10
  • OutStanding working for me........... – M Hamayun zeb Jan 24 '22 at 07:43
67

No Delegate Needed

You can create an action outlet from the UITextField for the "Primary Action Triggered" and resign first responder on the sender parameter passed in:

Create Action Outlet

@IBAction func done(_ sender: UITextField) {
    sender.resignFirstResponder()
}

Super simple.

(Thanks to Scott Smith's 60-second video for tipping me off about this: https://youtu.be/v6GrnVQy7iA)

Blazej SLEBODA
  • 8,936
  • 7
  • 53
  • 93
Mark Moeykens
  • 15,915
  • 6
  • 63
  • 62
  • if we have multiple textfields on a page then do we need to do it for each text field... – DragonFire Jul 09 '19 at 01:28
  • @DragonFire You can assign multiple textfields to the same outlet. Just drag from the Primary Action Triggered outlet in the outlet inspector (left side of the screen) to the IBAction in your code – Brad Root Sep 14 '19 at 21:15
  • It's good to note that dragging directly from the text field in the storyboard will default the linked action to Editing Did End, instead of Primary Action Triggered, so it should be done from the sidebar's Connections Inspector. – Cloud May 17 '20 at 13:35
  • 1
    Amazing. I did not know that. Thanks. – Numan Karaaslan May 24 '20 at 11:29
  • Also works with Swift 2, if anyone still cares. Thanks. – siralexsir88 May 26 '20 at 00:45
  • 1
    Thank you so much. This is exactly what I needed. I needed to dismiss a keyboard by the return button in a tableview cell. Works perfectly. –  Jun 29 '20 at 00:27
45
  • Add UITextFieldDelegate to the class declaration:

    class ViewController: UIViewController, UITextFieldDelegate
    
  • Connect the textfield or write it programmatically

    @IBOutlet weak var userText: UITextField!
    
  • set your view controller as the text fields delegate in view did load:

    override func viewDidLoad() {
    super.viewDidLoad()
    self.userText.delegate = self
    }
    
  • Add the following function

    func textFieldShouldReturn(userText: UITextField!) -> Bool {
        userText.resignFirstResponder()
        return true;
    }
    

    with all this your keyboard will begin to dismiss by touching outside the textfield aswell as by pressing return key.

Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
Codetard
  • 2,441
  • 28
  • 34
  • Thanks man! I was missing this: `UITextFieldDelegate` ... thanks a lot! – Adriano Tadao Dec 19 '15 at 00:23
  • For some reason, when I set the txtField.delegate = self , I can not type within that textfield once I run the app – Jesus Rodriguez May 23 '16 at 06:04
  • @JesusAdolfoRodriguez there must be a reason behind that error, tho this code isn't cause any issue. :D Happy coding! – Codetard Jul 22 '16 at 12:24
  • Thank you for the step by step. This was more helpful for me than just a block of code. – kenhkelly Sep 29 '16 at 12:32
  • 2
    "with all this your keyboard will begin to dismiss by touching outside the textfield" - Not true. textFieldShouldReturn is called only on pressing of the return button. – Jurasic Dec 09 '16 at 14:10
30

I hate to add the same function to every UIViewController. By extending UIViewController to support UITextFieldDelegate, you can provide a default behavior of "return pressed".

extension UIViewController: UITextFieldDelegate{
    public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true;
    }
}

When you create new UIViewController and UITextField, all you have to do is to write one line code in your UIViewController.

override func viewDidLoad() {
    super.viewDidLoad()
    textField.delegate = self
}

You can even omit this one line code by hooking delegate in Main.storyboard. (Using "ctrl" and drag from UITextField to UIViewController)

Wu Yuan Chun
  • 1,116
  • 11
  • 11
  • This is what I'm looking for, but I wish that resign firstresponder was default behavior or a setting. Setting a million delegates to self seems like a waste of time even if it's only a few per controller – James Joshua Street Mar 05 '21 at 08:10
22

Simple Swift 3 Solution: Add this function to your view controllers that feature a text field:

@IBAction func textField(_ sender: AnyObject) {
    self.view.endEditing(true);
}

Then open up your assistant editor and ensure both your Main.storyboard is on one side of your view and the desired view controller.swift file is on the other. Click on a text field and then select from the right hand side utilities panel 'Show the Connection Inspector' tab. Control drag from the 'Did End on Exit' to the above function in your swift file. Repeat for any other textfield in that scene and link to the same function.

elarcoiris
  • 1,914
  • 4
  • 28
  • 30
20

@RSC

for me the critical addition in Xcode Version 6.2 (6C86e) is in override func viewDidLoad()

 self.input.delegate = self;

Tried getting it to work with the return key for hours till I found your post, RSC. Thank you!

Also, if you want to hide the keyboard if you touch anywhere else on the screen:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        self.view.endEditing(true);
    }
Tobias F. Meier
  • 321
  • 2
  • 4
13

To get automatic keyboard dismissal, I put this code inside one of the methods of my custom text field's class:

textField.addTarget(nil, action:"firstResponderAction:", forControlEvents:.EditingDidEndOnExit)

Substitute your outlet's name for textField.

peacetype
  • 1,928
  • 3
  • 29
  • 49
  • 1
    Outstanding. This is the shortest and best option in my opinion. Especially when you're creating a text field inside another method. Like inside a table view header. – kakubei Jan 28 '16 at 12:26
  • Sorry, where exactly do you have to put this and what do you have to do to make it close the keyboard? I put `mytextfield.addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit)` (Swift 5 version) into `viewDidLoad` but neither return nor tapping somewhere outside the textfield worked. I got the textfields by creating an outlet each. – Neph Jun 27 '19 at 15:22
  • I put it in a subclass of a custom class that inherits from UIViewController. The subclass also conforms to UITextViewDelegate and UITextFieldDelegate. I put it in the ```viewDidAppear``` method of that class. ```UIAlertController.addTextField(configurationHandler: {(textField: UITextField!) in textField.delegate = self textField.addTarget(self, action: #selector(MySubclass.textChanged(_:)), for: .editingChanged) })``` This might be a little too specific to my case, but hopefully it helps. Try making the call within ```viewDidAppear``` and conforming to any delegates if necessary. – peacetype Jun 27 '19 at 18:29
10

Another way of doing this which mostly uses the storyboard and easily allows you to have multiple text fields is:

@IBAction func resignKeyboard(sender: AnyObject) {
    sender.resignFirstResponder()
}

Connect all your text fields for that view controller to that action on the Did End On Exit event of each field.

James Thompson
  • 101
  • 1
  • 2
  • Sorry for the bump, but I'm trying this method in my app and it doesn't seem to be working. I have a text field in the navigation bar and I've connected it to this action with that event as you said, but it doesn't work on runtime. – wasimsandhu Mar 26 '16 at 22:22
  • This would crash if sender is of type UIBarButtonItem. If I add toolbar with Done button to numeric keypad then your code is bound to crash with unrecognized selector sent to instance log. – Jayprakash Dubey Jul 26 '16 at 06:17
9

Here's the Swift 3.0 update to peacetype's comment:

textField.addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit)
jomafer
  • 2,655
  • 1
  • 32
  • 47
Darth Flyeater
  • 151
  • 1
  • 5
8

I would sugest to init the Class from RSC:

import Foundation
import UIKit

// Don't forget the delegate!
class ViewController: UIViewController, UITextFieldDelegate {

required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

@IBOutlet var myTextField : UITextField?

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    self.myTextField.delegate = self;
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func textFieldShouldReturn(textField: UITextField!) -> Bool {
    self.view.endEditing(true);
    return false;
}

}

papay0
  • 1,311
  • 1
  • 12
  • 25
LAOMUSIC ARTS
  • 642
  • 2
  • 10
  • 15
8

When the user taps the Done button on the text keyboard, a Did End On Exit event will be generated; at that time, we need to tell the text field to give up control so that the keyboard will go away. In order to do that, we need to add an action method to our controller class. Select ViewController.swift add the following action method:

@IBAction func textFieldDoneEditing(sender: UITextField) {
sender.resignFirstResponder()}

Select Main.storyboard in the Project Navigator and bring up the connections inspector. Drag from the circle next to Did End On Exit to the yellow View Controller icon in the storyboard and let go. A small pop-up menu will appear containing the name of a single action, the one we just added. Click the textFieldDoneEditing action to select it and that's it.

5

Swift 3

Add this code below to your VC

//hide keyboard when user tapps on return key on the keyboard
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    self.view.endEditing(true);
    return false;
}

Works for me

Gilad Brunfman
  • 3,452
  • 1
  • 29
  • 29
5

Swift

Using optional function from UITextFieldDelegate.

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    textField.endEditing(false)
}

false means that field can be ask to resign. true – force resign.

dimpiax
  • 12,093
  • 5
  • 62
  • 45
5
override func viewDidLoad() {
    super.viewDidLoad()

    let tap = UITapGestureRecognizer(target: self, action: #selector(handleScreenTap(sender:)))
    self.view.addGestureRecognizer(tap)}

then you use this function

func handleScreenTap(sender: UITapGestureRecognizer) {
    self.view.endEditing(true)
}
3

Make sure that your textField delegate is set to the view controller from which you are writing your textfield related code in.

self.textField.delegate = self
Miladinho
  • 174
  • 2
  • 11
2

you can put this anywhere but not in a UIButton

 func TextFieldEndEditing(text fiend name: UITextField!) -> Bool
{
    return (false)
}

then you can put this code in a button(also for example):

self.view.endEditing(true)

this worked for me

2

In the view controller you are using:

//suppose you are using the textfield label as this

@IBOutlet weak var emailLabel: UITextField!
@IBOutlet weak var passwordLabel: UITextField!

//then your viewdidload should have the code like this
override func viewDidLoad() {
        super.viewDidLoad()

        self.emailLabel.delegate = self
        self.passwordLabel.delegate = self

    }

//then you should implement the func named textFieldShouldReturn
 func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }

// -- then, further if you want to close the keyboard when pressed somewhere else on the screen you can implement the following method too:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true);
    }
kanishk verma
  • 382
  • 2
  • 9
0

you should connect the UITextfied with a delegate of view controller to make this function called

Abdulrahman Masoud
  • 1,096
  • 8
  • 12
0

All in One Hide Keyboard and Move View on Keyboard Open: Swift 5

override func viewDidLoad() {
    super.viewDidLoad()
    let tap = UITapGestureRecognizer(target: self, action: #selector(taped))
    view.addGestureRecognizer(tap)
    NotificationCenter.default.addObserver(self, selector: #selector(KeyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(KeyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}


   override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(true)
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}
 @objc func taped(){
    
    self.view.endEditing(true)
    
}

@objc func KeyboardWillShow(sender: NSNotification){
    
    let keyboardSize : CGSize = ((sender.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.size)!
    if self.view.frame.origin.y == 0{
        self.view.frame.origin.y -= keyboardSize.height
    }
    
    
}

@objc func KeyboardWillHide(sender : NSNotification){
    
    let keyboardSize : CGSize = ((sender.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size)!
    if self.view.frame.origin.y != 0{
        self.view.frame.origin.y += keyboardSize.height
    }
    
}


func textFieldShouldReturn(_ textField: UITextField) -> Bool { 
    textField.resignFirstResponder()
    return true
}
Imran Rasheed
  • 825
  • 10
  • 25