ScrollView and keyboard in Swift
In ViewDidLoad, register the notifications:
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name:UIResponder.keyboardWillShowNotification, object: nil)NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name:UIResponder.keyboardWillHideNotification, object: nil)
Add below observer methods which does the automatic scrolling when keyboard appears.
@objc func keyboardWillShow(notification:NSNotification) { guard let userInfo = notification.userInfo else { return } var keyboardFrame:CGRect = (userInfo[UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue keyboardFrame = self.view.convert(keyboardFrame, from: nil) var contentInset:UIEdgeInsets = self.scrollView.contentInset contentInset.bottom = keyboardFrame.size.height + 20 scrollView.contentInset = contentInset}@objc func keyboardWillHide(notification:NSNotification) { let contentInset:UIEdgeInsets = UIEdgeInsets.zero scrollView.contentInset = contentInset}
The top answer for swift 3:
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name:NSNotification.Name.UIKeyboardWillShow, object: nil)NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name:NSNotification.Name.UIKeyboardWillHide, object: nil)
And then:
func keyboardWillShow(notification:NSNotification){ //give room at the bottom of the scroll view, so it doesn't cover up anything the user needs to tap var userInfo = notification.userInfo! var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue keyboardFrame = self.view.convert(keyboardFrame, from: nil) var contentInset:UIEdgeInsets = self.theScrollView.contentInset contentInset.bottom = keyboardFrame.size.height theScrollView.contentInset = contentInset}func keyboardWillHide(notification:NSNotification){ let contentInset:UIEdgeInsets = UIEdgeInsets.zero theScrollView.contentInset = contentInset}
Here is a complete solution, utilizing guard and concise code. Plus correct code in keyboardWillHide
to only reset the bottom
to 0.
@IBOutlet private weak var scrollView: UIScrollView!override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) registerNotifications()}override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) scrollView.contentInset.bottom = 0}private func registerNotifications() { NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)}@objc private func keyboardWillShow(notification: NSNotification){ guard let keyboardFrame = notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return } scrollView.contentInset.bottom = view.convert(keyboardFrame.cgRectValue, from: nil).size.height}@objc private func keyboardWillHide(notification: NSNotification){ scrollView.contentInset.bottom = 0}