Skip to content

Instantly share code, notes, and snippets.

@jugyo
Last active January 14, 2021 16:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jugyo/8ea683cee0f526e6070db6c0af5970df to your computer and use it in GitHub Desktop.
Save jugyo/8ea683cee0f526e6070db6c0af5970df to your computer and use it in GitHub Desktop.
import UIKit
class FloatingView: UIView {
var keyboardSize: CGFloat = 0
open var height: CGFloat = 56 {
didSet {
self.setNeedsDisplay()
}
}
open var paddingY: CGFloat = 0 {
didSet {
self.setNeedsDisplay()
}
}
/**
Initialize with custom frame.
*/
public override init(frame: CGRect) {
super.init(frame: frame)
height = frame.size.height
backgroundColor = UIColor.clear
layer.zPosition = 1000
setObserver()
}
/**
Initialize from storyboard.
*/
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Method
public func setFrameToBottom() {
if superview == nil {
frame = CGRect(
x: 0,
y: (UIScreen.main.bounds.size.height - height - keyboardSize) - paddingY,
width: UIScreen.main.bounds.size.width,
height: height
)
} else {
if let scrollView = superview as? UIScrollView {
frame = CGRect(
x: scrollView.contentOffset.x,
y: (superview!.bounds.size.height - height - keyboardSize - paddingY) + scrollView.contentOffset.y,
width: superview!.bounds.size.width,
height: height
)
} else {
frame = CGRect(
x: 0,
y: (superview!.bounds.size.height - height - keyboardSize) - paddingY,
width: superview!.bounds.size.width,
height: height
)
}
}
}
fileprivate func setObserver() {
NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChange(_:)), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name:NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name:NSNotification.Name.UIKeyboardWillHide, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
NotificationCenter.default.removeObserver(self, name:NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name:NSNotification.Name.UIKeyboardWillHide, object: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
setFrameToBottom()
}
override func willMove(toSuperview newSuperview: UIView?) {
superview?.removeObserver(self, forKeyPath: "frame")
superview?.removeObserver(self, forKeyPath: "contentOffset")
super.willMove(toSuperview: newSuperview)
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
superview?.addObserver(self, forKeyPath: "frame", options: [], context: nil)
superview?.addObserver(self, forKeyPath: "contentOffset", options: .new, context:nil)
}
internal func deviceOrientationDidChange(_ notification: Notification) {
guard let keyboardSize: CGFloat = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size.height else {
self.keyboardSize = 0
return
}
self.keyboardSize = keyboardSize
setFrameToBottom()
}
internal func keyboardWillShow(_ notification: Notification) {
guard let keyboardSize: CGFloat = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size.height else {
self.keyboardSize = 0
return
}
self.keyboardSize = keyboardSize
UIView.animate(withDuration: 0.2, delay: 0, options: UIViewAnimationOptions(), animations: {
self.setFrameToBottom()
}, completion: nil)
}
internal func keyboardWillHide(_ notification: Notification) {
self.keyboardSize = 0
UIView.animate(withDuration: 0.2, delay: 0, options: UIViewAnimationOptions(), animations: {
self.setFrameToBottom()
}, completion: nil)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment