Skip to content

Instantly share code, notes, and snippets.

@TomQDRS
Last active January 9, 2019 09:53
Show Gist options
  • Save TomQDRS/f6bcde7c50b2f24d650966290e3c00dd to your computer and use it in GitHub Desktop.
Save TomQDRS/f6bcde7c50b2f24d650966290e3c00dd to your computer and use it in GitHub Desktop.
This piece of code should help you if the iOS keyboard hides essential views upon being shown.
// SETUP REQUIRED:
// The setup requires a Storyboard setup with an empty, clear view called `keyboardSpacer`.
// That view should be placed below the elements that you want to be pushed up when the keyboard appears.
// Give that view a height constraint and connect that constraint to `keyboardSpacerHeightConstraint`.
// The static value for that height (thes size when the keyboard isn't shown) should be jotted down in `staticHeightForKeyboardSpacer`.
// This can also be simplified by making `staticHeightForKeyboardSpacer` inspectable.
// The following functions will change the height constraint of the `keyboardSpacer` view depending on the keyboard status,
// making sure that the spacer view will be the same height as the keyboard when it is shown or changed and revert to the original size when it is hidden.
/// The height constraint for the spacer view that pushes up the layout when the keyboard shows.
@IBOutlet var keyboardSpacerHeightConstraint: NSLayoutConstraint!
/// The height that the constraint should have when the keyboard is hidden.
let staticHeightForKeyboardSpacer = 128
// Called when the view is about appear
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Register for keyboard change notifications so we can move the view when the keyboard is shown or hidden.
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
/** keyboardWillChangeFrame(notification)
is called when the controller receives the notification that the keyboard will change frame.
This function takes the frame that the keyboard will have at the end of the transition and sets
the spacer view's height to the frame's height. This way, the keyboard won't overlay the user input
elements.
*/
@objc func keyboardWillChangeFrame(notification: Notification) {
/// The size the keyboard's frame will change to.
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
// Animate the height constraint change so it's not choppy.
UIView.animate(withDuration: 0.25) {
self.keyboardSpacerHeightConstraint.constant = keyboardSize.height
self.view.layoutIfNeeded()
}
}
}
/** keyboardWillHide(notification)
is called when the controller receives the notification that the keyboard will hide. This happens
after the `keyboardWillChangeFrame(notification)` function is called, making it perfect to actually
remove the keyboard from view.
This function takes the static value that the spacer view should have withot the keyboard being shown
(`staticHeightForKeyboardSpacer`) and resets the view to that value.
*/
@objc func keyboardWillHide(notification: Notification) {
// Animate the height constraint change so it's not choppy.
UIView.animate(withDuration: 0.25) {
self.keyboardSpacerHeightConstraint.constant = CGFloat(self.staticHeightForKeyboardSpacer)
self.view.layoutIfNeeded()
}
}
// Called when the view is about to disappear.
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Remove the view as an observer for the keyboard notifications so no problems happen with calling them twice.
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment