Skip to content

Instantly share code, notes, and snippets.

@syousif94
Created May 1, 2020 07:43
Show Gist options
  • Save syousif94/a356fec45eba2307be871f06226fe227 to your computer and use it in GitHub Desktop.
Save syousif94/a356fec45eba2307be871f06226fe227 to your computer and use it in GitHub Desktop.
handle keyboard notifications in swift
class ViewController: UIViewController, KeyboardObserverDelegate {
let keyboardObserver = KeyboardObserver()
let scrollView = UIScrollView()
let randomView = UIView()
func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
keyboardObserver.delegate = self
}
func keyboardDidChange(_ keyboard: KeyboardNotification) {
if keyboard.willShow {
scrollView.contentInset.bottom = keyboard.endHeight
keyboard.animate {
self.randomView.transform = CGAffineTransform(translateX: 0, translateY: -keyboard.endHeight)
}
}
else {
scrollView.contentInset.bottom = 0
keyboard.animate {
self.randomView.transform = .identity
}
}
}
}
import UIKit
import NotificationCenter
protocol KeyboardObserverDelegate: class {
func keyboardWillChange(_ keyboard: KeyboardNotification)
}
class KeyboardObserver: NSObject {
weak var delegate: KeyboardObserverDelegate?
override init() {
super.init()
NotificationCenter.default.addObserver(self, selector: #selector(handleNotification(_:)), name: UIApplication.keyboardWillChangeFrameNotification, object: nil)
}
@objc func handleNotification(_ notification: Notification) {
guard let keyboardNotification = KeyboardNotification(notification) else {
return
}
delegate?.keyboardWillChange(keyboardNotification)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
struct KeyboardNotification {
let duration: TimeInterval
let animationCurve: UIView.AnimationOptions
let willShow: Bool
let endHeight: CGFloat
init?(_ notification: Notification) {
guard let userInfo = notification.userInfo,
let startFrame = (userInfo[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue,
let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
let animationCurveRawNSN = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber,
let duration:TimeInterval = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue else { return nil }
self.duration = duration
let animationCurveRaw = animationCurveRawNSN.uintValue
self.animationCurve = UIView.AnimationOptions(rawValue: animationCurveRaw)
self.willShow = endFrame.origin.y < UIScreen.main.bounds.height
self.endHeight = endFrame.height
}
func animate(animations: @escaping () -> Void) {
animate(animations: animations, completion: nil)
}
func animate(animations: @escaping () -> Void, completion: ((Bool) -> Void)?) {
UIView.animate(
withDuration: duration,
delay: 0.0,
options: animationCurve,
animations: animations,
completion: completion
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment