Skip to content

Instantly share code, notes, and snippets.

@joshavant
Last active March 11, 2016 21:47
Show Gist options
  • Save joshavant/a2f676008f01e996c064 to your computer and use it in GitHub Desktop.
Save joshavant/a2f676008f01e996c064 to your computer and use it in GitHub Desktop.
A basic, thin wrapper on keyboard appearance handling. This is mostly just a starting point: this only updates its `var currentMetrics`, which leaves to the user the exercise of adding whatever update hooks make sense for their codebase (likely through subclassing).
//
// KeyboardMetricsService.swift
// CrowdRise
//
// Created by Josh Avant on 3/10/16.
// Copyright © 2016 CrowdRise. All rights reserved.
//
import UIKit
class KeyboardMetricsService: NSObject {
struct Metrics {
let beginFrame: CGRect
let endFrame: CGRect
let animationDuration: Double
let animationCurve: UInt // rawValue for UIViewAnimationCurve
init(userInfo: [NSObject : AnyObject]) {
let beginFrameValue = userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue ?? NSValue(CGRect: CGRect.zero)
beginFrame = beginFrameValue.CGRectValue()
let endFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue ?? NSValue(CGRect: CGRect.zero)
endFrame = endFrameValue.CGRectValue()
let animationDurationNumber = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber ?? NSNumber(double: 0)
animationDuration = animationDurationNumber.doubleValue
let animationCurveNumber = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber ?? NSNumber(unsignedInteger: 0)
animationCurve = animationCurveNumber.unsignedIntegerValue
}
}
enum ChangeType {
case WillChange
case DidChange
}
private(set) var currentMetrics: Metrics?
// Injected Dependencies
var notificationCenter: NSNotificationCenter? {
willSet {
if notificationCenter != nil {
removeObservers()
}
}
didSet {
if notificationCenter != nil {
addObservers()
}
}
}
func handleKeyboardMetricsChange(changeType: ChangeType, metrics: Metrics) {
currentMetrics = metrics
}
private func addObservers() {
self.notificationCenter?.addObserver(self,
selector: "keyboardWillChangeFrameNotification:",
name: UIKeyboardWillChangeFrameNotification,
object: nil)
self.notificationCenter?.addObserver(self,
selector: "keyboardDidChangeFrameNotification:",
name: UIKeyboardDidChangeFrameNotification,
object: nil)
}
private func removeObservers() {
self.notificationCenter?.removeObserver(self,
name: UIKeyboardWillChangeFrameNotification,
object: nil)
self.notificationCenter?.removeObserver(self,
name: UIKeyboardDidChangeFrameNotification,
object: nil)
}
private dynamic func keyboardWillChangeFrameNotification(notification: NSNotification) {
if let userInfo = notification.userInfo {
let metrics = Metrics(userInfo: userInfo)
self.handleKeyboardMetricsChange(.WillChange, metrics: metrics)
}
}
private dynamic func keyboardDidChangeFrameNotification(notification: NSNotification) {
if let userInfo = notification.userInfo {
let metrics = Metrics(userInfo: userInfo)
self.handleKeyboardMetricsChange(.DidChange, metrics: metrics)
}
}
deinit {
removeObservers()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment