Skip to content

Instantly share code, notes, and snippets.

@marcisme
Created November 17, 2016 03:31
Show Gist options
  • Save marcisme/9187a92c76a721d17dd8038cef1fc1aa to your computer and use it in GitHub Desktop.
Save marcisme/9187a92c76a721d17dd8038cef1fc1aa to your computer and use it in GitHub Desktop.
class KeyboardDodger {
private struct KeyboardValues {
private let userInfo: [AnyHashable : Any]
init(notification: Notification) {
userInfo = (notification as NSNotification).userInfo!
}
var duration: TimeInterval {
return userInfo[UIKeyboardAnimationDurationUserInfoKey] as! TimeInterval
}
var frame: CGRect {
return (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
}
var curve: UIViewAnimationOptions {
return UIViewAnimationOptions(rawValue: userInfo[UIKeyboardAnimationCurveUserInfoKey] as! UInt)
}
}
private let view: UIView
private let constraint: NSLayoutConstraint
private let collisionView: UIView
private let notificationCenter = NotificationCenter.default
private let offset: CGFloat = 8
init (view: UIView, constraint: NSLayoutConstraint, collisionView: UIView) {
self.view = view
self.constraint = constraint
self.collisionView = collisionView
addObservers()
}
private func addObservers() {
notificationCenter.addObserver(self, selector: #selector(KeyboardDodger.keyboardWillChangeFrame(_:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
notificationCenter.addObserver(self, selector: #selector(KeyboardDodger.keyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
deinit {
notificationCenter.removeObserver(self)
}
private dynamic func keyboardWillChangeFrame(_ notification: Notification) {
let values = KeyboardValues(notification: notification)
updateConstraint(values)
animateView(values)
}
private func updateConstraint(_ values: KeyboardValues) {
if !collisionView.frame.intersects(values.frame) { return }
constraint.constant = values.frame.height + offset
view.addConstraint(constraint)
view.setNeedsUpdateConstraints()
}
private func animateView(_ values: KeyboardValues) {
UIView.animate(withDuration: values.duration, delay: 0, options: values.curve, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}
private dynamic func keyboardWillHide(_ notification: Notification) {
let values = KeyboardValues(notification: notification)
removeConstraint()
animateView(values)
}
private func removeConstraint() {
constraint.constant = 0
view.removeConstraint(constraint)
view.setNeedsUpdateConstraints()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment