Created
September 13, 2018 22:06
-
-
Save joshavant/56f3abdfad0e5ac0bdc6ea3c0913f555 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// | |
// KeyboardInsettable.swift | |
// | |
// Created by Josh Avant on 9/11/18. | |
// | |
import Foundation | |
import UIKit | |
protocol KeyboardInsettable { | |
var keyboardInsettableScrollView: UIScrollView { get } | |
static var defaultScrollViewContentInset: UIEdgeInsets { get } | |
func registerForKeyboardNotifications(willChangeFrameSelector selector: Selector) | |
func handleKeyboardWillChangeFrame(notification: Notification) | |
} | |
// NOTE: Does not support adjustable iPad keyboard. | |
extension KeyboardInsettable { | |
func registerForKeyboardNotifications(willChangeFrameSelector selector: Selector) { | |
NotificationCenter.default.addObserver(self, selector: selector, name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil) | |
} | |
func handleKeyboardWillChangeFrame(notification: Notification) { | |
guard let keyboardFrame = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue, | |
let animationDuration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, | |
let animationCurve = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber, | |
let window = UIApplication.shared.keyWindow, | |
let superview = self.keyboardInsettableScrollView.superview else { return } | |
let scrollViewYMinimum = window.convert(self.keyboardInsettableScrollView.frame, from: superview).minY | |
let scrollViewYMaximum = scrollViewYMinimum + self.keyboardInsettableScrollView.frame.height | |
let scrollViewYCoordinateRange = scrollViewYMinimum..<scrollViewYMaximum | |
let keyboardYMinimum = keyboardFrame.origin.y | |
let keyboardYMaximum = keyboardYMinimum + keyboardFrame.size.height | |
let keyboardYCoordinateRange = keyboardYMinimum..<keyboardYMaximum | |
let overlappingYCoordinateRange = scrollViewYCoordinateRange.clamped(to: keyboardYCoordinateRange) | |
let overlapAmount = overlappingYCoordinateRange.upperBound - overlappingYCoordinateRange.lowerBound | |
let newContentInsets = UIEdgeInsets(top: Self.defaultScrollViewContentInset.top, | |
left: Self.defaultScrollViewContentInset.left, | |
bottom: Self.defaultScrollViewContentInset.bottom + overlapAmount, | |
right: Self.defaultScrollViewContentInset.right) | |
let newIndicatorInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: overlapAmount, right: 0.0) | |
let curve = UIViewAnimationOptions(rawValue: animationCurve.uintValue) | |
UIView.animate(withDuration: animationDuration.doubleValue, delay: 0, options: curve, animations: { | |
self.keyboardInsettableScrollView.contentInset = newContentInsets | |
self.keyboardInsettableScrollView.scrollIndicatorInsets = newIndicatorInsets | |
}, completion: nil) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment