Create a gist now

Instantly share code, notes, and snippets.

Embed
Swift implementation of Soroush Khanlou's keyboard manager view controller
extension UIEdgeInsets {
static var zero: UIEdgeInsets {
return UIEdgeInsetsZero
}
}
// Inspired by "Many Controllers Make Light Work" by Soroush Khanlou
// http://khanlou.com/2016/02/many-controllers/
class KeyboardManagerViewController: UIViewController {
let scrollView: UIScrollView
let center = NSNotificationCenter.defaultCenter()
var oldInsets: UIEdgeInsets = UIEdgeInsets.zero
init(scrollView: UIScrollView) {
self.scrollView = scrollView
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.alpha = 0.0
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
center.addObserver(self, selector: "keyboardAppeared:", name:UIKeyboardDidShowNotification, object: nil)
center.addObserver(self, selector: "keyboardDisappeared:", name:UIKeyboardWillHideNotification, object: nil)
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
center.removeObserver(self, name:UIKeyboardDidShowNotification, object: nil)
center.removeObserver(self, name:UIKeyboardWillHideNotification, object: nil)
}
// Inspired by https://github.com/irace/BRYParseKeyboardNotification
typealias KeyboardNotificationInfo = (duration: NSTimeInterval, height: CGFloat, animationOptions: UIViewAnimationOptions)
func parseKeyboardNotification(notification: NSNotification) -> KeyboardNotificationInfo? {
guard let userInfo = notification.userInfo else { return nil }
guard let duration: NSTimeInterval = userInfo[UIKeyboardAnimationDurationUserInfoKey]?.doubleValue else { return nil }
// Convert animation curve to animation options: https://devforums.apple.com/message/878410#878410
guard let optionsInteger = userInfo[UIKeyboardAnimationCurveUserInfoKey]?.unsignedIntegerValue else { return nil }
let options = UIViewAnimationOptions(rawValue: optionsInteger << 16)
guard let keyboardFrame = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue else { return nil }
return (duration: duration, height: keyboardFrame.height, animationOptions: options)
}
func keyboardAppeared(notification: NSNotification) {
guard let info = parseKeyboardNotification(notification) else { return }
oldInsets = scrollView.contentInset
let newInsets = UIEdgeInsets(top: oldInsets.top, left: 0, bottom: info.height, right: 0)
scrollView.contentInset = newInsets
scrollView.scrollIndicatorInsets = newInsets
}
func keyboardDisappeared(notification: NSNotification) {
scrollView.contentInset = oldInsets
scrollView.scrollIndicatorInsets = oldInsets
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment