103 lines
3.8 KiB
Swift
103 lines
3.8 KiB
Swift
//
|
|
// ScrollingViewController.swift
|
|
// MVMCoreUI
|
|
//
|
|
// Created by Scott Pfeil on 3/12/20.
|
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
open class ScrollingViewController: ViewController {
|
|
public var dismissKeyboardTapGesture: UITapGestureRecognizer?
|
|
@IBOutlet public var scrollView: UIScrollView!
|
|
public var contentView: UIView?
|
|
|
|
private var keyboardNotificationsAdded = false
|
|
private var keyboardIsShowing = false
|
|
private var preKeyboardContentInset: UIEdgeInsets?
|
|
|
|
public init(with scrollView: UIScrollView) {
|
|
self.scrollView = scrollView
|
|
super.init(nibName: nil, bundle: nil)
|
|
}
|
|
|
|
required public init?(coder: NSCoder) {
|
|
super.init(coder: coder)
|
|
}
|
|
|
|
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
|
|
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
|
|
}
|
|
|
|
// MARK: - View Life Cycle
|
|
open override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
// Adds the tap gesture to dismiss the keyboard.
|
|
dismissKeyboardTapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissFieldInput))
|
|
view.addGestureRecognizer(dismissKeyboardTapGesture!)
|
|
dismissKeyboardTapGesture?.isEnabled = false
|
|
scrollView.alwaysBounceVertical = false
|
|
scrollView.delegate = self
|
|
}
|
|
|
|
open override func viewDidLayoutSubviews() {
|
|
super.viewDidLayoutSubviews()
|
|
view.setNeedsUpdateConstraints()
|
|
view.layoutSubviews()
|
|
}
|
|
|
|
open override func viewWillAppear(_ animated: Bool) {
|
|
super.viewWillAppear(animated)
|
|
registerForKeyboardNotifications()
|
|
}
|
|
|
|
// MARK: - Keyboard Handling
|
|
open func registerForKeyboardNotifications() {
|
|
if !keyboardNotificationsAdded {
|
|
keyboardNotificationsAdded = true
|
|
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
|
|
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
|
|
}
|
|
}
|
|
|
|
open func unregisterForKeyboardNotifications() {
|
|
if keyboardNotificationsAdded {
|
|
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
|
|
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
|
|
keyboardNotificationsAdded = false
|
|
}
|
|
}
|
|
|
|
@objc open func keyboardWillShow(notification: Notification) {
|
|
// Stores the current scroll insets if the keyboard was hidden.
|
|
if !keyboardIsShowing {
|
|
preKeyboardContentInset = scrollView.contentInset
|
|
}
|
|
keyboardIsShowing = true
|
|
|
|
// Enables the tap gesture.
|
|
dismissKeyboardTapGesture?.isEnabled = true
|
|
|
|
MVMCoreUIUtility.setScrollViewInsetForKeyboardShow(notification, scrollView: scrollView, viewController: self) { [weak self] () -> CGRect in
|
|
return self?.rectToScrollToWhenKeyboardPopsUp() ?? .zero
|
|
}
|
|
}
|
|
|
|
@objc open func keyboardWillBeHidden(notification: Notification) {
|
|
keyboardIsShowing = false
|
|
|
|
// Disables the tap gesture.
|
|
dismissKeyboardTapGesture?.isEnabled = false
|
|
|
|
MVMCoreUIUtility.setScrollViewInsetForKeyboardHide(notification, scrollView: scrollView, viewController: self, contentInset: preKeyboardContentInset ?? scrollView.contentInset)
|
|
}
|
|
|
|
open func rectToScrollToWhenKeyboardPopsUp() -> CGRect? {
|
|
guard let field = selectedField,
|
|
let parent = selectedField?.superview else { return nil }
|
|
return scrollView.convert(field.frame, from: parent)
|
|
}
|
|
}
|