Skip to content

Instantly share code, notes, and snippets.

@Ankit-Aggarwal
Last active January 11, 2020 03:57
Show Gist options
  • Save Ankit-Aggarwal/b61dd72dad4b0c6602afc73440138f51 to your computer and use it in GitHub Desktop.
Save Ankit-Aggarwal/b61dd72dad4b0c6602afc73440138f51 to your computer and use it in GitHub Desktop.
UIViewController Extension to handle keyboard updates easily
import Foundation
import UIKit
import ReactiveSwift
import Result
extension UIViewController {
typealias KeyboardStatusInfo = (height: CGFloat , duration: TimeInterval, animationOptions: UIViewAnimationOptions)
var keyboardUpdatesSignal: Signal<KeyboardStatusInfo, NoError> {
let center = NotificationCenter.default.reactive
let willShowProducer = center.notifications(forName: .UIKeyboardWillShow).map {
[weak self] (notification) -> KeyboardStatusInfo? in
self?.parsekeyboardNotification(notification: notification)
}.skipNil()
let willHideProducer = center.notifications(forName: .UIKeyboardWillHide).map {
[weak self] (notification) -> KeyboardStatusInfo? in
self?.parsekeyboardNotification(notification: notification)
}.skipNil()
return Signal.merge([willShowProducer, willHideProducer])
}
func parsekeyboardNotification(notification: Notification) -> KeyboardStatusInfo? {
guard UIApplication.shared.applicationState != .background else {
return (0, 0, UIViewAnimationOptions.curveEaseInOut)
}
guard let info = notification.userInfo else {
return nil
}
guard let frame = (info[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else {
return nil
}
let height = UIScreen.main.bounds.height - frame.origin.y // height above screen
guard let duration = info[UIKeyboardAnimationDurationUserInfoKey] as? TimeInterval else {
return nil
}
guard let curveRaw = info[UIKeyboardAnimationCurveUserInfoKey] as? Int else {
return nil
}
let options = UIViewAnimationOptions(rawValue: UInt(curveRaw) << 16)
return (height, duration, options)
}
var appDidEnterBGSignal: Signal<Notification, NoError> {
return NotificationCenter.default.reactive.notifications(forName: .UIApplicationDidEnterBackground)
}
var appWillEnterFGSignal: Signal<Notification, NoError> {
return NotificationCenter.default.reactive.notifications(forName: .UIApplicationWillEnterForeground)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment