While building an iOS app recently, we struggled a bit to resize the scroll view on keyboard appearance. Since the solution is not so straight, we decided to document it for everyone else to use.
This is how it looks like:
And here’s how we did it-
In your ViewController implement UITextFieldDelegate. In viewDidLoad() add following code:
//Setting delegate for textfield
myFirstTextField.delegate = self
mySecondTextField.delegate = self
Add following optional variable to the ViewController:
/* this will hold the current text field being edited */
var currentTextField:UITextField?
/* this will hold the contentoffset of the scrollview before resizing of the scrollview, this will be used to restore the content offset of scroll view when keyboard is hidden */
var lastOffset:CGPoint?
//this will hold the height of keyboard
var keyboardHeight:CGFloat?
We need to add following two actions from UITextFieldDelegate:
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
currentTextField = textField
lastOffset = self.scrollView.contentOffset
return true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
currentTextField?.resignFirstResponder()
currentTextField = nil
return true
}
Now add following two observers:
@objc func keyboardWillShow(notification: NSNotification) {
if keyboardHeight != nil {
return
}
//UIKeyboardFrameBeginUserInfoKey
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.size {
keyboardHeight = keyboardSize.height
UIView.animate(withDuration: 0.3, animations: {
self.constraintContentHeight.constant += self.keyboardHeight!
})
let distanceToBottom = self.scrollView.frame.size.height - (currentTextField?.frame.origin.y)! - (currentTextField?.frame.size.height)!
let collapseSpace = keyboardHeight! - distanceToBottom
if collapseSpace < 0 {
return
}
UIView.animate(withDuration: 0.3, animations: {
//Your scrollview will scroll to 5 coordinates above the keyboard
self.scrollView.contentOffset = CGPoint(x: (self.lastOffset?.x)!, y: collapseSpace + 5)
})
}
}
@objc func keyboardWillHide(notification: NSNotification) {
if self.keyboardHeight != nil{
UIView.animate(withDuration: 0.3) {
self.constraintContentHeight.constant -= self.keyboardHeight!
self.scrollView.contentOffset = self.lastOffset!
}
keyboardHeight = nil
}
}
In viewDidLoad() add two functions as observers:
//Adding observers
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: Notification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: Notification.Name.UIKeyboardWillHide, object: nil)