Best way to dismiss Keyboard in a View Controller iOS (Swift)


I was thinking to discuss all possible ways to dismiss the keyboard in iOS app and figure out which one is best suited one.

UITextFields has keyboard as there first responders, as soon you begin editing keyboard shows up. It is developer’s responsibility to write code to dismiss it.
Let me explain few methods how to do it especially when there are multiple UITextFields on your view controller.

First way: Implement textFieldShouldReturn delegate in the view controller and dismiss each keyboard.

func textFieldShouldReturn(textField: UITextField) -> Bool {
self.textField1.resignFirstResponder()
self.textField2.resignFirstResponder()
return true
}

this solution could be cumbersome when you have too may textfields in your View Controller.

Second way: In textFieldShouldReturn delegate implementation you can call self.view’s method endEditing.

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

neat and clean, is’nt it?

Third way: the second way might be best way except in one case where the keyboard does’t have return key , e.g. numberpad (UIKeyboardType.NumberPad)

the work around could be adding UIToolbar on top and set a target method

override func viewDidLoad() {
super.viewDidLoad()
   //init toolbar
let toolbar:UIToolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 30))
   //create left side empty space so that done button set on right side
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
   let doneBtn: UIBarButtonItem = UIBarButtonItem(title: “Done”, style: .done, target: self, action: Selector(“doneButtonAction”))
   toolbar.setItems([flexSpace, doneBtn], animated: false)
toolbar.sizeToFit()
   //setting toolbar as inputAccessoryView
self.textField1.inputAccessoryView = toolbar
self.textField2.inputAccessoryView = toolbar
}
func doneButtonAction() {
self.view.endEditing(true)
}

Fourth: what could be better than tapping anywhere on the view controller to dismiss the keyboard. Just one line of code would serve our purpose. Add a tap gesture recognizer on self.view, set target as self.view and set selector as endEditing: (in ViewDidLoad() or anywhere you like)

self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: Selector(“endEditing:”)))

thats it?

As Uncle Ben said “Great power comes with great responsibility”, there could be issues if you are dealing with Table Views and adding above tap gesture. You might get issues while selecting the rows, didSelectRowAtIndex path could not be fired until pressed long.

so there is solution for that. Modify above code as below.

let tap = UITapGestureRecognizer(target: self.view, action: Selector(“endEditing:”))
tap.cancelsTouchesInView = false
self.view.addGestureRecognizer(tap)

Just make sure cancelsTouchesInView is set false.

Addtional:
As Jeff Scaturro has pointed out another cool way to do it. Override the touchesBegan function of viewController and call endEditing on self.view

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
      self.view.endEditing(true)
}

*Please suggest if you have any more ways to do this.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.