Created
March 18, 2016 10:24
-
-
Save DeFrenZ/a742fbfb4e72bb849849 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// DZKeyboardLayoutProxyView.swift | |
// | |
// Created by Davide De Franceschi on 25/02/2015. | |
// | |
import UIKit | |
final class DZKeyboardLayoutProxyView: UIView { | |
private var keyboardObserver: NSObjectProtocol? | |
@IBOutlet weak var delegate: DZKeyboardLayoutProxyViewDelegate? | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
commonInit() | |
} | |
required init?(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
commonInit() | |
} | |
private func commonInit() { | |
translatesAutoresizingMaskIntoConstraints = true | |
startObservingKeyboardNotifications() | |
} | |
override func awakeFromNib() { | |
super.awakeFromNib() | |
frame = CGRect(x: 0, y: superview!.bounds.height, width: superview!.bounds.width, height: 0) | |
backgroundColor = .clearColor() | |
opaque = false | |
alpha = 0 | |
hidden = true | |
} | |
deinit { | |
stopObservingKeyboardNotifications() | |
} | |
} | |
private let changeKeyboardAnimateLayoutDuration: NSTimeInterval = 0.2 | |
extension DZKeyboardLayoutProxyView { | |
private func startObservingKeyboardNotifications() { | |
keyboardObserver = NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardWillChangeFrameNotification, object: nil, queue: nil) { [weak self] notification in | |
guard | |
let sself = self, | |
let notificationInfo = notification.userInfo | |
else { return } | |
let startFrame = (notificationInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue() | |
let endFrame = (notificationInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue() | |
guard endFrame != startFrame else { return } | |
let animationCurveOptions = UIViewAnimationOptions(rawValue: (notificationInfo[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber).unsignedLongValue) | |
let notificationAnimationDuration = (notificationInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue as NSTimeInterval | |
let animationDuration = notificationAnimationDuration > 0 ? notificationAnimationDuration : changeKeyboardAnimateLayoutDuration | |
let newFrame = sself.superview?.convertRect(endFrame, fromView: nil) ?? .zero | |
let callDelegateWillChangeFrame: () -> () | |
let callDelegateDidChangeFrame: () -> () | |
if let delegate = sself.delegate { | |
callDelegateWillChangeFrame = { delegate.keyboardProxyView(sself, willChangeFrameToFrame: newFrame) } | |
callDelegateDidChangeFrame = { delegate.keyboardProxyView(sself, didChangeFrameToFrame: newFrame) } | |
} else { | |
callDelegateWillChangeFrame = {} | |
callDelegateDidChangeFrame = {} | |
} | |
let animationOptions = animationCurveOptions ∪ .BeginFromCurrentState | |
let animations: () -> () = { | |
sself.superview?.layoutIfNeeded() | |
callDelegateDidChangeFrame() | |
} | |
let updateFrame: () -> () = { () -> () in | |
callDelegateWillChangeFrame() | |
sself.frame = newFrame | |
UIView.animateWithDuration(animationDuration, delay: 0, options: animationOptions, animations: animations, completion: nil) | |
return | |
} | |
dispatch_sync_main(updateFrame) | |
} | |
} | |
private func stopObservingKeyboardNotifications() { | |
if let observer = keyboardObserver { | |
NSNotificationCenter.defaultCenter().removeObserver(observer) | |
} | |
} | |
} | |
@objc protocol DZKeyboardLayoutProxyViewDelegate: NSObjectProtocol { | |
func keyboardProxyView(keyboardView: DZKeyboardLayoutProxyView, willChangeFrameToFrame frame: CGRect) | |
func keyboardProxyView(keyboardView: DZKeyboardLayoutProxyView, didChangeFrameToFrame frame: CGRect) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment