Respond to the appearing and disappearing of the keyboard and also dismiss it by ‘outside’ taps in similar fashion to Android.
Note that it is important to remove the observer (to dismiss the keyboard) as soon as you leave the ViewController
, otherwise you will end up with overlapping gesture recognizers. If you use this ViewController
as a super to another ViewController
you can overwrite keyboardWillShow
and keyboardWillHide
. In the snippet they pan the view according to the size of the keyboard.
import UIKit
class BaseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard(_:)))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(sender:)), name: Notification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(sender:)), name: Notification.Name.UIKeyboardWillHide, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self)
}
@objc func keyboardWillShow(sender: Notification) {
if(self.view.frame.origin.y == 0 ) {
if let keyboardFrame: NSValue = sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
let keyboardRectangle = keyboardFrame.cgRectValue
let keyboardHeight = keyboardRectangle.height
self.view.frame.origin.y = -keyboardHeight
}
}
}
@objc func keyboardWillHide(sender: Notification) {
if self.view.frame.origin.y != 0 {
self.view.frame.origin.y = 0
}
}
@objc func dismissKeyboard(_ sender: AnyObject) {
view.endEditing(true)
}
}