// // ScrollingViewController.swift // MVMCoreUI // // Created by Scott Pfeil on 3/12/20. // Copyright © 2020 Verizon Wireless. All rights reserved. // open class ScrollingViewController: ViewController { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- 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? //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- 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 Lifecycle //-------------------------------------------------- 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() } open override func updateUI() { super.updateUI() // will change scrollView indicatorStyle automatically on the basis of backgroundColor var greyScale: CGFloat = 0 if view.backgroundColor?.getWhite(&greyScale, alpha: nil) ?? false { scrollView.indicatorStyle = greyScale > 0.5 ? .black : .white } scrollView.flashScrollIndicators() } open func scrollViewDidScroll(_ scrollView: UIScrollView) { executeBehaviors { [weak self] (behavior: PageScrolledBehavior) in behavior.pageScrolled(scrollView: scrollView, self?.delegateObjectIVar) } } //-------------------------------------------------- // 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) } }