Skip to content

Instantly share code, notes, and snippets.

@brownsoo
Created April 9, 2018 09:31
Show Gist options
  • Save brownsoo/854412d3845fbb41d96c497371f64b70 to your computer and use it in GitHub Desktop.
Save brownsoo/854412d3845fbb41d96c497371f64b70 to your computer and use it in GitHub Desktop.
Responsive to keyboard frame in iOS
// in UIViewController
func setupHideKeypadWhenTappedAround() {
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
// responsive keyboard frame
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillChange),
name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
}
@objc
private func handleTap(sender: UITapGestureRecognizer) {
// hide keyboard
view.endEditing(true)
}
@objc
private func handleKeyboardWillChange(sender: Notification) {
// parsing notification
let n = KeyboardNotification(sender)
let keyboardFrame = n.frameEndForView(view: self.view)
let duration = n.animationDuration
let curve = n.animationCurve
var frame: CGRect = self.view.frame
frame.size = CGSize(width: frame.size.width, height: keyboardFrame.minY)
willChangeViewFrame(frame, duration: duration, option: UIViewAnimationOptions(rawValue: UInt(curve << 16)))
}
/// Notify a view of UIViewController will be changes its frame
func willChangeViewFrame(_ to: CGRect, duration: Double, option: UIViewAnimationOptions) {
}
///
/// Helper struct to parse Notification of UIKeyboardWillChangeFrame
import UIKit
// https://gist.github.com/kristopherjohnson/13d5f18b0d56b0ea9242
/// Wrapper for the NSNotification userInfo values associated with a keyboard notification.
///
/// It provides properties that retrieve userInfo dictionary values with these keys:
///
/// - UIKeyboardFrameBeginUserInfoKey
/// - UIKeyboardFrameEndUserInfoKey
/// - UIKeyboardAnimationDurationUserInfoKey
/// - UIKeyboardAnimationCurveUserInfoKey
public struct KeyboardNotification {
let notification: Notification
let userInfo: Dictionary<String, Any>
/// Initializer
///
/// :param: notification Keyboard-related notification
public init(_ notification: Notification) {
self.notification = notification
if let userInfo = notification.userInfo {
self.userInfo = userInfo as! Dictionary
} else {
self.userInfo = Dictionary()
}
}
/// Start frame of the keyboard in screen coordinates
public var screenFrameBegin: CGRect {
if let value = userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue {
return value.cgRectValue
} else {
return CGRect.zero
}
}
/// End frame of the keyboard in screen coordinates
public var screenFrameEnd: CGRect {
if let value = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue {
return value.cgRectValue
} else {
return CGRect.zero
}
}
/// keyboard animation duration
public var animationDuration: Double {
if let number = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber {
return number.doubleValue
} else {
return 0.25
}
}
/// Keyboard animation curve
///
/// Note that the value returned by this method may not correspond to a
/// UIViewAnimationCurve enum value. For example, in iOS 7 and iOS 8,
/// this returns the value 7.
public var animationCurve: Int {
if let number = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber {
return number.intValue
}
return UIViewAnimationCurve.easeInOut.rawValue
}
/// Start frame of the keyboard in coordinates of specified view
///
/// :param: view UIView to whose coordinate system the frame will be converted
/// :returns: frame rectangle in view's coordinate system
public func frameBeginForView(view: UIView) -> CGRect {
return view.convert(screenFrameBegin, from: view.window)
}
/// End frame of the keyboard in coordinates of specified view
///
/// :param: view UIView to whose coordinate system the frame will be converted
/// :returns: frame rectangle in view's coordinate system
public func frameEndForView(view: UIView) -> CGRect {
return view.convert(screenFrameEnd, from: view.window)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment