Merge branch 'feature/keyboard_responsiveness' into 'develop'
TextView Keyboard responsiveness See merge request BPHV_MIPS/mvm_core_ui!549
This commit is contained in:
commit
b428d76129
@ -6,9 +6,12 @@
|
|||||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
open class ScrollingViewController: ViewController {
|
open class ScrollingViewController: ViewController {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public var dismissKeyboardTapGesture: UITapGestureRecognizer?
|
public var dismissKeyboardTapGesture: UITapGestureRecognizer?
|
||||||
@IBOutlet public var scrollView: UIScrollView!
|
@IBOutlet public var scrollView: UIScrollView!
|
||||||
public var contentView: UIView?
|
public var contentView: UIView?
|
||||||
@ -17,6 +20,10 @@ open class ScrollingViewController: ViewController {
|
|||||||
private var keyboardIsShowing = false
|
private var keyboardIsShowing = false
|
||||||
private var preKeyboardContentInset: UIEdgeInsets?
|
private var preKeyboardContentInset: UIEdgeInsets?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public init(with scrollView: UIScrollView) {
|
public init(with scrollView: UIScrollView) {
|
||||||
self.scrollView = scrollView
|
self.scrollView = scrollView
|
||||||
super.init(nibName: nil, bundle: nil)
|
super.init(nibName: nil, bundle: nil)
|
||||||
@ -30,7 +37,10 @@ open class ScrollingViewController: ViewController {
|
|||||||
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
|
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - View Life Cycle
|
//--------------------------------------------------
|
||||||
|
// MARK: - View Lifecycle
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func viewDidLoad() {
|
open override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
@ -53,7 +63,10 @@ open class ScrollingViewController: ViewController {
|
|||||||
registerForKeyboardNotifications()
|
registerForKeyboardNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - Keyboard Handling
|
// MARK: - Keyboard Handling
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open func registerForKeyboardNotifications() {
|
open func registerForKeyboardNotifications() {
|
||||||
if !keyboardNotificationsAdded {
|
if !keyboardNotificationsAdded {
|
||||||
keyboardNotificationsAdded = true
|
keyboardNotificationsAdded = true
|
||||||
@ -95,8 +108,11 @@ open class ScrollingViewController: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open func rectToScrollToWhenKeyboardPopsUp() -> CGRect? {
|
open func rectToScrollToWhenKeyboardPopsUp() -> CGRect? {
|
||||||
|
|
||||||
guard let field = selectedField,
|
guard let field = selectedField,
|
||||||
let parent = selectedField?.superview else { return nil }
|
let parent = selectedField?.superview
|
||||||
|
else { return nil }
|
||||||
|
|
||||||
return scrollView.convert(field.frame, from: parent)
|
return scrollView.convert(field.frame, from: parent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,12 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
|
||||||
@objc open class ViewController: UIViewController, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MoleculeDelegateProtocol, FormHolderProtocol, MVMCoreActionDelegateProtocol, MVMCoreLoadDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, ObservingTextFieldDelegate, MVMCoreUIDetailViewProtocol {
|
@objc open class ViewController: UIViewController, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MoleculeDelegateProtocol, FormHolderProtocol, MVMCoreActionDelegateProtocol, MVMCoreLoadDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, ObservingTextFieldDelegate, MVMCoreUIDetailViewProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
@objc public var pageType: String?
|
@objc public var pageType: String?
|
||||||
@objc public var loadObject: MVMCoreLoadObject?
|
@objc public var loadObject: MVMCoreLoadObject?
|
||||||
public var pageModel: MVMControllerModelProtocol?
|
public var pageModel: MVMControllerModelProtocol?
|
||||||
@ -39,10 +44,15 @@ import UIKit
|
|||||||
return !MVMCoreGetterUtility.cgfequalwiththreshold(previousScreenSize.width, view.bounds.size.width, 0.1)
|
return !MVMCoreGetterUtility.cgfequalwiththreshold(previousScreenSize.width, view.bounds.size.width, 0.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - Response handling
|
// MARK: - Response handling
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open func observeForResponseJSONUpdates() {
|
open func observeForResponseJSONUpdates() {
|
||||||
guard !observingForResponses,
|
guard !observingForResponses,
|
||||||
(pagesToListenFor()?.count ?? 0 > 0 || modulesToListenFor()?.count ?? 0 > 0) else { return }
|
(pagesToListenFor()?.count ?? 0 > 0 || modulesToListenFor()?.count ?? 0 > 0)
|
||||||
|
else { return }
|
||||||
|
|
||||||
observingForResponses = true
|
observingForResponses = true
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(responseJSONUpdated(notification:)), name: NSNotification.Name(rawValue: NotificationResponseLoaded), object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(responseJSONUpdated(notification:)), name: NSNotification.Name(rawValue: NotificationResponseLoaded), object: nil)
|
||||||
}
|
}
|
||||||
@ -69,7 +79,9 @@ import UIKit
|
|||||||
let pageType = pagesToListenFor()?.first(where: { (pageTypeListened) -> Bool in
|
let pageType = pagesToListenFor()?.first(where: { (pageTypeListened) -> Bool in
|
||||||
guard let page = pagesLoaded.optionalDictionaryForKey(pageTypeListened),
|
guard let page = pagesLoaded.optionalDictionaryForKey(pageTypeListened),
|
||||||
let pageType = page.optionalStringForKey(KeyPageType),
|
let pageType = page.optionalStringForKey(KeyPageType),
|
||||||
pageType == pageTypeListened else { return false }
|
pageType == pageTypeListened
|
||||||
|
else { return false }
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}) {
|
}) {
|
||||||
newData = true
|
newData = true
|
||||||
@ -90,6 +102,7 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
guard newData else { return }
|
guard newData else { return }
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try parsePageJSON()
|
try parsePageJSON()
|
||||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||||
@ -134,8 +147,10 @@ import UIKit
|
|||||||
switch (registryError) {
|
switch (registryError) {
|
||||||
case .decoderErrorModelNotMapped(let identifier, let codingKey, let codingPath) where identifier != nil && codingKey != nil && codingPath != nil:
|
case .decoderErrorModelNotMapped(let identifier, let codingKey, let codingPath) where identifier != nil && codingKey != nil && codingPath != nil:
|
||||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Model identifier \"\(identifier!)\" is not mapped for \"\(codingKey!.stringValue)\" @ \(codingPath!.map { return $0.stringValue })")
|
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Model identifier \"\(identifier!)\" is not mapped for \"\(codingKey!.stringValue)\" @ \(codingPath!.map { return $0.stringValue })")
|
||||||
|
|
||||||
case .decoderErrorObjectNotPresent(let codingKey, codingPath: let codingPath):
|
case .decoderErrorObjectNotPresent(let codingKey, codingPath: let codingPath):
|
||||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Required model \"\(codingKey.stringValue)\" was not found @ \(codingPath.map { return $0.stringValue })")
|
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Required model \"\(codingKey.stringValue)\" was not found @ \(codingPath.map { return $0.stringValue })")
|
||||||
|
|
||||||
default:
|
default:
|
||||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Registry error: \(registryError)")
|
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Registry error: \(registryError)")
|
||||||
}
|
}
|
||||||
@ -144,24 +159,29 @@ import UIKit
|
|||||||
switch (decodingError) {
|
switch (decodingError) {
|
||||||
case .keyNotFound(let codingKey, let context):
|
case .keyNotFound(let codingKey, let context):
|
||||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })")
|
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })")
|
||||||
|
|
||||||
case .valueNotFound(_, let context):
|
case .valueNotFound(_, let context):
|
||||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Value not found @ \(context.codingPath.map { return $0.stringValue })")
|
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Value not found @ \(context.codingPath.map { return $0.stringValue })")
|
||||||
|
|
||||||
case .typeMismatch(_, let context):
|
case .typeMismatch(_, let context):
|
||||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Type mismatch @ \(context.codingPath.map { return $0.stringValue })")
|
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Type mismatch @ \(context.codingPath.map { return $0.stringValue })")
|
||||||
|
|
||||||
case .dataCorrupted(let context):
|
case .dataCorrupted(let context):
|
||||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Data corrupted @ \(context.codingPath.map { return $0.stringValue })")
|
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Data corrupted @ \(context.codingPath.map { return $0.stringValue })")
|
||||||
|
|
||||||
@unknown default:
|
@unknown default:
|
||||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: \(parsingError)")
|
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: \(parsingError)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open func parsePageJSON() throws {
|
open func parsePageJSON() throws { }
|
||||||
}
|
|
||||||
|
|
||||||
open class func verifyRequiredModulesLoaded(for loadObject: MVMCoreLoadObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
|
open class func verifyRequiredModulesLoaded(for loadObject: MVMCoreLoadObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
|
||||||
guard let pageType = loadObject?.pageType, var modulesRequired = MVMCoreUIViewControllerMappingObject.shared()?.modulesRequired(forPageType: pageType),
|
guard let pageType = loadObject?.pageType,
|
||||||
!modulesRequired.isEmpty else { return true }
|
var modulesRequired = MVMCoreUIViewControllerMappingObject.shared()?.modulesRequired(forPageType: pageType),
|
||||||
|
!modulesRequired.isEmpty
|
||||||
|
else { return true }
|
||||||
|
|
||||||
guard let loadedModules = loadObject?.modulesJSON else { return false }
|
guard let loadedModules = loadObject?.modulesJSON else { return false }
|
||||||
|
|
||||||
@ -210,7 +230,9 @@ import UIKit
|
|||||||
setNavigationItem()
|
setNavigationItem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - Navigation Item (Move to model base)
|
// MARK: - Navigation Item (Move to model base)
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open func getNavigationModel() -> NavigationItemModelProtocol? {
|
open func getNavigationModel() -> NavigationItemModelProtocol? {
|
||||||
// TODO: remove legacy. Temporary, convert legacy to navigation model.
|
// TODO: remove legacy. Temporary, convert legacy to navigation model.
|
||||||
@ -224,7 +246,8 @@ import UIKit
|
|||||||
/// Sets the navigation item for this view controller.
|
/// Sets the navigation item for this view controller.
|
||||||
open func setNavigationItem() {
|
open func setNavigationItem() {
|
||||||
guard let navigationItemModel = getNavigationModel(),
|
guard let navigationItemModel = getNavigationModel(),
|
||||||
let navigationController = navigationController else { return }
|
let navigationController = navigationController
|
||||||
|
else { return }
|
||||||
|
|
||||||
// We additionally want our left items
|
// We additionally want our left items
|
||||||
navigationItem.leftItemsSupplementBackButton = true
|
navigationItem.leftItemsSupplementBackButton = true
|
||||||
@ -238,8 +261,8 @@ import UIKit
|
|||||||
let viewController = manager ?? self
|
let viewController = manager ?? self
|
||||||
guard let navigationItemModel = getNavigationModel(),
|
guard let navigationItemModel = getNavigationModel(),
|
||||||
let navigationController = viewController.navigationController else {
|
let navigationController = viewController.navigationController else {
|
||||||
MVMCoreUISession.sharedGlobal()?.splitViewController?.parent?.setNeedsStatusBarAppearanceUpdate()
|
MVMCoreUISession.sharedGlobal()?.splitViewController?.parent?.setNeedsStatusBarAppearanceUpdate()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utilize helper function to set the split view and navigation item state.
|
// Utilize helper function to set the split view and navigation item state.
|
||||||
@ -268,18 +291,16 @@ import UIKit
|
|||||||
|
|
||||||
// Eventually will be moved to separate button in navigation item model
|
// Eventually will be moved to separate button in navigation item model
|
||||||
open func isOverridingRightButton() -> Bool {
|
open func isOverridingRightButton() -> Bool {
|
||||||
guard let rightPanelLink = loadObject?.pageJSON?.optionalDictionaryForKey("rightPanelButtonLink") else {
|
guard let rightPanelLink = loadObject?.pageJSON?.optionalDictionaryForKey("rightPanelButtonLink")
|
||||||
return false
|
else { return false }
|
||||||
}
|
|
||||||
MVMCoreActionHandler.shared()?.handleAction(with: rightPanelLink, additionalData: nil, delegateObject: delegateObject())
|
MVMCoreActionHandler.shared()?.handleAction(with: rightPanelLink, additionalData: nil, delegateObject: delegateObject())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eventually will be moved to separate button in navigation item model
|
// Eventually will be moved to separate button in navigation item model
|
||||||
open func isOverridingLeftButton() -> Bool {
|
open func isOverridingLeftButton() -> Bool {
|
||||||
guard let leftPanelLink = loadObject?.pageJSON?.optionalDictionaryForKey("leftPanelButtonLink") else {
|
guard let leftPanelLink = loadObject?.pageJSON?.optionalDictionaryForKey("leftPanelButtonLink")
|
||||||
return false
|
else { return false }
|
||||||
}
|
|
||||||
MVMCoreActionHandler.shared()?.handleAction(with: leftPanelLink, additionalData: nil, delegateObject: delegateObject())
|
MVMCoreActionHandler.shared()?.handleAction(with: leftPanelLink, additionalData: nil, delegateObject: delegateObject())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -287,11 +308,15 @@ import UIKit
|
|||||||
// Eventually will be moved to Model
|
// Eventually will be moved to Model
|
||||||
open func bottomProgress() -> Float? {
|
open func bottomProgress() -> Float? {
|
||||||
guard let progressString = loadObject?.pageJSON?.optionalStringForKey(KeyProgressPercent),
|
guard let progressString = loadObject?.pageJSON?.optionalStringForKey(KeyProgressPercent),
|
||||||
let progress = Float(progressString) else { return nil }
|
let progress = Float(progressString)
|
||||||
return (progress / Float(100))
|
else { return nil }
|
||||||
}
|
|
||||||
|
|
||||||
|
return progress / Float(100)
|
||||||
|
}
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - TabBar
|
// MARK: - TabBar
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open func updateTabBar() {
|
open func updateTabBar() {
|
||||||
guard MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() == self,
|
guard MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() == self,
|
||||||
let tabModel = pageModel as? TabPageModelProtocol else { return }
|
let tabModel = pageModel as? TabPageModelProtocol else { return }
|
||||||
@ -302,7 +327,9 @@ import UIKit
|
|||||||
MVMCoreUISplitViewController.main()?.updateTabBarShowing(!tabModel.tabBarHidden)
|
MVMCoreUISplitViewController.main()?.updateTabBarShowing(!tabModel.tabBarHidden)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - View lifecycle
|
//--------------------------------------------------
|
||||||
|
// MARK: - View Lifecycle
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
/// Called only once in viewDidLoad
|
/// Called only once in viewDidLoad
|
||||||
open func initialLoad() {
|
open func initialLoad() {
|
||||||
@ -401,18 +428,22 @@ import UIKit
|
|||||||
super.viewWillTransition(to: size, with: coordinator)
|
super.viewWillTransition(to: size, with: coordinator)
|
||||||
|
|
||||||
// Updates the detail view width
|
// Updates the detail view width
|
||||||
coordinator.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) in
|
coordinator.animate(alongsideTransition: { UIViewControllerTransitionCoordinatorContext in
|
||||||
}) { (UIViewControllerTransitionCoordinatorContext) in
|
}) { UIViewControllerTransitionCoordinatorContext in
|
||||||
self.view.setNeedsLayout()
|
self.view.setNeedsLayout()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - MVMCoreViewManagerViewControllerProtocol
|
// MARK: - MVMCoreViewManagerViewControllerProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open func viewControllerReady(inManager manager: UIViewController & MVMCoreViewManagerProtocol) {
|
open func viewControllerReady(inManager manager: UIViewController & MVMCoreViewManagerProtocol) {
|
||||||
pageShown()
|
pageShown()
|
||||||
}
|
}
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - MVMCoreLoadDelegateProtocol
|
// MARK: - MVMCoreLoadDelegateProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
// TODO: Move this function out of here after architecture cleanup.
|
// TODO: Move this function out of here after architecture cleanup.
|
||||||
open func loadFinished(_ loadObject: MVMCoreLoadObject?, loadedViewController: (UIViewController & MVMCoreViewControllerProtocol)?, error: MVMCoreErrorObject?) {
|
open func loadFinished(_ loadObject: MVMCoreLoadObject?, loadedViewController: (UIViewController & MVMCoreViewControllerProtocol)?, error: MVMCoreErrorObject?) {
|
||||||
|
|
||||||
@ -434,7 +465,10 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - MVMCoreActionDelegateProtocol
|
// MARK: - MVMCoreActionDelegateProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open func handleOpenPage(for requestParameters: MVMCoreRequestParameters, actionInformation: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?) {
|
open func handleOpenPage(for requestParameters: MVMCoreRequestParameters, actionInformation: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?) {
|
||||||
formValidator?.addFormParams(requestParameters: requestParameters)
|
formValidator?.addFormParams(requestParameters: requestParameters)
|
||||||
requestParameters.parentPageType = loadObject?.pageJSON?.optionalStringForKey("parentPageType")
|
requestParameters.parentPageType = loadObject?.pageJSON?.optionalStringForKey("parentPageType")
|
||||||
@ -445,7 +479,10 @@ import UIKit
|
|||||||
MVMCoreUILoggingHandler.shared()?.defaultLogAction(forController: self, actionInformation: actionInformation, additionalData: additionalData)
|
MVMCoreUILoggingHandler.shared()?.defaultLogAction(forController: self, actionInformation: actionInformation, additionalData: additionalData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - MoleculeDelegateProtocol
|
// MARK: - MoleculeDelegateProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open func getModuleWithName(_ name: String?) -> [AnyHashable: Any]? {
|
open func getModuleWithName(_ name: String?) -> [AnyHashable: Any]? {
|
||||||
guard let name = name else { return nil }
|
guard let name = name else { return nil }
|
||||||
return loadObject?.modulesJSON?.optionalDictionaryForKey(name)
|
return loadObject?.modulesJSON?.optionalDictionaryForKey(name)
|
||||||
@ -456,6 +493,7 @@ import UIKit
|
|||||||
let moleculeName = moduleJSON.optionalStringForKey("moleculeName"),
|
let moleculeName = moduleJSON.optionalStringForKey("moleculeName"),
|
||||||
let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self)
|
let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self)
|
||||||
else { return nil }
|
else { return nil }
|
||||||
|
|
||||||
do {
|
do {
|
||||||
return try modelType.decode(jsonDict: moduleJSON) as? MoleculeModelProtocol
|
return try modelType.decode(jsonDict: moduleJSON) as? MoleculeModelProtocol
|
||||||
} catch {
|
} catch {
|
||||||
@ -471,14 +509,19 @@ import UIKit
|
|||||||
open func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], indexPath: IndexPath, animation: UITableView.RowAnimation) {}
|
open func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], indexPath: IndexPath, animation: UITableView.RowAnimation) {}
|
||||||
open func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], animation: UITableView.RowAnimation) {}
|
open func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], animation: UITableView.RowAnimation) {}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - MVMCoreUIDetailViewProtocol
|
// MARK: - MVMCoreUIDetailViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
// Reset the navigation state.
|
// Reset the navigation state.
|
||||||
public func splitViewDidReset() {
|
public func splitViewDidReset() {
|
||||||
setNavigationBar()
|
setNavigationBar()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - UITextFieldDelegate (Check if this is still needed)
|
//--------------------------------------------------
|
||||||
|
// MARK: - UITextFieldDelegate
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
// To Remove TextFields Bug: Keyboard is not dismissing after reaching textfield max length limit
|
// To Remove TextFields Bug: Keyboard is not dismissing after reaching textfield max length limit
|
||||||
open func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
open func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||||
textField.resignFirstResponder()
|
textField.resignFirstResponder()
|
||||||
@ -490,9 +533,13 @@ import UIKit
|
|||||||
|
|
||||||
// TODO: Make this into a protocol
|
// TODO: Make this into a protocol
|
||||||
if UIAccessibility.isVoiceOverRunning {
|
if UIAccessibility.isVoiceOverRunning {
|
||||||
if let toolBar = textField.inputAccessoryView as? UIToolbar, let _ = toolBar.items?.last, let pickerView = textField.inputView as? UIPickerView {
|
if let toolBar = textField.inputAccessoryView as? UIToolbar,
|
||||||
|
let _ = toolBar.items?.last,
|
||||||
|
let pickerView = textField.inputView as? UIPickerView {
|
||||||
|
|
||||||
view.accessibilityElements = [pickerView, toolBar]
|
view.accessibilityElements = [pickerView, toolBar]
|
||||||
}
|
}
|
||||||
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||||
UIAccessibility.post(notification: .layoutChanged, argument: textField.inputView)
|
UIAccessibility.post(notification: .layoutChanged, argument: textField.inputView)
|
||||||
}
|
}
|
||||||
@ -500,11 +547,13 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
open func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
|
open func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
|
||||||
|
|
||||||
if textField === selectedField {
|
if textField === selectedField {
|
||||||
if UIAccessibility.isVoiceOverRunning {
|
if UIAccessibility.isVoiceOverRunning {
|
||||||
view.accessibilityElements = nil
|
view.accessibilityElements = nil
|
||||||
UIAccessibility.post(notification: .layoutChanged, argument: textField)
|
UIAccessibility.post(notification: .layoutChanged, argument: textField)
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedField = nil
|
selectedField = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -513,7 +562,15 @@ import UIKit
|
|||||||
selectedField?.resignFirstResponder()
|
selectedField?.resignFirstResponder()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - UITextViewDelegate (Check if this is still needed)
|
//--------------------------------------------------
|
||||||
|
// MARK: - UITextViewDelegate
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
|
||||||
|
selectedField = textView
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
open func textViewDidBeginEditing(_ textView: UITextView) {
|
open func textViewDidBeginEditing(_ textView: UITextView) {
|
||||||
selectedField = textView
|
selectedField = textView
|
||||||
}
|
}
|
||||||
@ -524,8 +581,11 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - Behavior Execution
|
// MARK: - Behavior Execution
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
func executeBehaviors<T>(_ behaviorBlock:(_ behavior:T)->Void) {
|
func executeBehaviors<T>(_ behaviorBlock:(_ behavior:T)->Void) {
|
||||||
pageModel?.behaviors?.compactMap({ $0 as? T }).forEach({ behaviorBlock($0) })
|
pageModel?.behaviors?.compactMap({ $0 as? T }).forEach { behaviorBlock($0) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user