decouple manager navigation setting a little better

This commit is contained in:
Pfeil, Scott Robert 2020-10-08 15:01:38 -04:00
parent 43bd436225
commit 2e12464016
3 changed files with 77 additions and 104 deletions

View File

@ -10,16 +10,6 @@ import Foundation
public protocol PageProtocol { public protocol PageProtocol {
var pageModel: PageModelProtocol? { get set } var pageModel: PageModelProtocol? { get set }
/// Sets the navigationBar property of the pageModel and attempts to refresh the ui.
mutating func updateNavigationBar(with model: NavigationItemModelProtocol & MoleculeModelProtocol)
}
extension PageProtocol {
mutating public func updateNavigationBar(with model: NavigationItemModelProtocol & MoleculeModelProtocol) {
pageModel?.navigationBar = model
(self as? NavigationBarRefreshProtocol)?.refreshNavigationUI()
}
} }
/// A protocol to inform that we should refresh the navigation bar ui. /// A protocol to inform that we should refresh the navigation bar ui.
@ -32,12 +22,13 @@ public extension UINavigationBar {
/// Convenience function to refresh the navigation bar ui. /// Convenience function to refresh the navigation bar ui.
@objc static func refreshNavigationUI(for viewController: UIViewController) { @objc static func refreshNavigationUI(for viewController: UIViewController) {
guard let model = (viewController as? PageProtocol)?.pageModel?.navigationBar else { return } guard let model = (viewController as? PageProtocol)?.pageModel?.navigationBar else { return }
if let manager = ((viewController as? MVMCoreViewManagerViewControllerProtocol)?.manager as? NavigationBarRefreshProtocol) { if let navigationController = viewController.navigationController {
// Go through the manager if possible.
manager.refreshNavigationUI()
} else if let navigationController = viewController.navigationController {
NavigationController.setNavigationItem(navigationController: navigationController, navigationItemModel: model, viewController: viewController) NavigationController.setNavigationItem(navigationController: navigationController, navigationItemModel: model, viewController: viewController)
MVMCoreUISplitViewController.setNavigationBarUI(for: viewController, navigationController: navigationController, navigationItemModel: model, leftPanelAccessible: (viewController as? MVMCoreUIDetailViewProtocol)?.isLeftPanelAccessible?(), rightPanelAccessible: (viewController as? MVMCoreUIDetailViewProtocol)?.isRightPanelAccessible?()) MVMCoreUISplitViewController.setNavigationBarUI(for: viewController, navigationController: navigationController, navigationItemModel: model)
}
if let manager = ((viewController as? MVMCoreViewManagerViewControllerProtocol)?.manager as? NavigationBarRefreshProtocol) {
// Refresh the manager if possible.
manager.refreshNavigationUI()
} }
} }
} }

View File

@ -119,14 +119,15 @@ import UIKit
MVMCoreDispatchUtility.performBlock(onMainThread: { MVMCoreDispatchUtility.performBlock(onMainThread: {
self.handleNewDataAndUpdateUI() self.handleNewDataAndUpdateUI()
// Update navigation bar if showing.
if MVMCoreUIUtility.getCurrentVisibleController() == self { if MVMCoreUIUtility.getCurrentVisibleController() == self {
if let manager = self.manager { // Update navigation bar if showing.
// Let manager handle self.setNavigationBar()
manager.refreshNavigationUI() self.manager?.refreshNavigationUI()
} else { }
self.setNavigationBar() // Update splitview properties
} if self == MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() {
MVMCoreUISplitViewController.main()?.setBottomProgressBarProgress(self.bottomProgress() ?? 0)
self.updateTabBar()
} }
}) })
} catch { } catch {
@ -140,7 +141,7 @@ import UIKit
pageType = loadObject.pageType pageType = loadObject.pageType
self.loadObject = loadObject self.loadObject = loadObject
// Verifies all modules needed are loaded. TODO: change to ViewController // Verifies all modules needed are loaded.
guard ViewController.verifyRequiredModulesLoaded(for: loadObject, error: error) else { return false } guard ViewController.verifyRequiredModulesLoaded(for: loadObject, error: error) else { return false }
// Parse the model for the page. // Parse the model for the page.
@ -247,7 +248,7 @@ import UIKit
} }
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Navigation Item (Move to model base) // MARK: - Navigation Item
//-------------------------------------------------- //--------------------------------------------------
open func getNavigationModel() -> NavigationItemModelProtocol? { open func getNavigationModel() -> NavigationItemModelProtocol? {
@ -271,61 +272,16 @@ import UIKit
/// Sets the appearance of the navigation bar based on the model. /// Sets the appearance of the navigation bar based on the model.
open func setNavigationBar() { open func setNavigationBar() {
let viewController = manager ?? self
guard let navigationItemModel = getNavigationModel(), guard let navigationItemModel = getNavigationModel(),
let navigationController = viewController.navigationController else { let navigationController = 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.
MVMCoreUISplitViewController.setNavigationBarUI(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel, leftPanelAccessible: isMasterInitiallyAccessible(), rightPanelAccessible: isSupportInitiallyAccessible(), progress: bottomProgress() ?? 0) MVMCoreUISplitViewController.setNavigationBarUI(for: self, navigationController: navigationController, navigationItemModel: navigationItemModel)
} }
// Eventually will be moved to server
open func isMasterInitiallyAccessible() -> Bool {
if loadObject?.pageJSON?.boolForKey(KeyHideMainMenu) ?? false {
return false
}
return MVMCoreUISession.sharedGlobal()?.launchAppLoadedSuccessfully ?? false
}
// Eventually will be moved to server
open func isSupportInitiallyAccessible() -> Bool {
if loadObject?.pageJSON?.boolForKey(KeyHideMainMenu) ?? false {
return false
}
return (MVMCoreUISession.sharedGlobal()?.launchAppLoadedSuccessfully ?? false) || showRightPanelForScreenBeforeLaunchApp()
}
open func showRightPanelForScreenBeforeLaunchApp() -> Bool {
return loadObject?.pageJSON?.lenientBoolForKey("showRightPanel") ?? false
}
// Eventually will be moved to separate button in navigation item model
open func isOverridingRightButton() -> Bool {
guard let rightPanelLink = loadObject?.pageJSON?.optionalDictionaryForKey("rightPanelButtonLink")
else { return false }
MVMCoreActionHandler.shared()?.handleAction(with: rightPanelLink, additionalData: nil, delegateObject: delegateObject())
return true
}
// Eventually will be moved to separate button in navigation item model
open func isOverridingLeftButton() -> Bool {
guard let leftPanelLink = loadObject?.pageJSON?.optionalDictionaryForKey("leftPanelButtonLink")
else { return false }
MVMCoreActionHandler.shared()?.handleAction(with: leftPanelLink, additionalData: nil, delegateObject: delegateObject())
return true
}
// Eventually will be moved to Model
open func bottomProgress() -> Float? {
guard let progressString = loadObject?.pageJSON?.optionalStringForKey(KeyProgressPercent),
let progress = Float(progressString)
else { return nil }
return progress / Float(100)
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - TabBar // MARK: - TabBar
//-------------------------------------------------- //--------------------------------------------------
@ -408,14 +364,15 @@ import UIKit
} }
open func pageShown() { open func pageShown() {
// Update the navigation bar ui when view is appearing. // Update split view properties if this is the current detail controller.
if self == MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() { if self == MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() {
MVMCoreUISplitViewController.main()?.setupPanels() MVMCoreUISplitViewController.main()?.setupPanels()
MVMCoreUISplitViewController.main()?.setBottomProgressBarProgress(bottomProgress() ?? 0)
updateTabBar()
} }
setNavigationBar()
// Update tab if needed. // Update the navigation bar ui when view is appearing.
updateTabBar() setNavigationBar()
// Track. // Track.
MVMCoreUISession.sharedGlobal()?.currentPageType = pageType MVMCoreUISession.sharedGlobal()?.currentPageType = pageType
@ -536,6 +493,51 @@ import UIKit
setNavigationBar() setNavigationBar()
} }
public func isLeftPanelAccessible() -> Bool {
// TODO: Remove when hamburger menu is fully phased out.
if loadObject?.pageJSON?.boolForKey(KeyHideMainMenu) ?? false {
return false
}
return MVMCoreUISession.sharedGlobal()?.launchAppLoadedSuccessfully ?? false
}
public func isRightPanelAccessible() -> Bool {
// TODO: Remove when FAB is 100%.
if loadObject?.pageJSON?.boolForKey(KeyHideMainMenu) ?? false {
return false
}
return (MVMCoreUISession.sharedGlobal()?.launchAppLoadedSuccessfully ?? false) || showRightPanelForScreenBeforeLaunchApp()
}
open func showRightPanelForScreenBeforeLaunchApp() -> Bool {
return loadObject?.pageJSON?.lenientBoolForKey("showRightPanel") ?? false
}
// TODO: make molecular
open func isOverridingRightButton() -> Bool {
guard let rightPanelLink = loadObject?.pageJSON?.optionalDictionaryForKey("rightPanelButtonLink")
else { return false }
MVMCoreActionHandler.shared()?.handleAction(with: rightPanelLink, additionalData: nil, delegateObject: delegateObject())
return true
}
// TODO: make molecular
open func isOverridingLeftButton() -> Bool {
guard let leftPanelLink = loadObject?.pageJSON?.optionalDictionaryForKey("leftPanelButtonLink")
else { return false }
MVMCoreActionHandler.shared()?.handleAction(with: leftPanelLink, additionalData: nil, delegateObject: delegateObject())
return true
}
// Eventually will be moved to Model
open func bottomProgress() -> Float? {
guard let progressString = loadObject?.pageJSON?.optionalStringForKey(KeyProgressPercent),
let progress = Float(progressString)
else { return nil }
return progress / Float(100)
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - UITextFieldDelegate // MARK: - UITextFieldDelegate
//-------------------------------------------------- //--------------------------------------------------

View File

@ -10,32 +10,29 @@ import Foundation
public extension MVMCoreUISplitViewController { public extension MVMCoreUISplitViewController {
/// Convenience function. Sets the navigation and split view properties for the view controller. Optional parameters use current value if not set. /// Convenience function. Sets the navigation and split view properties for the view controller. Panel access is determined if view controller is a detail view protocol.
static func setNavigationBarUI(for viewController: UIViewController, navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, leftPanelAccessible: Bool? = nil, rightPanelAccessible: Bool? = nil, progress: Float? = nil) { static func setNavigationBarUI(for viewController: UIViewController, navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol) {
guard let splitView = MVMCoreUISplitViewController.main(), guard let splitView = MVMCoreUISplitViewController.main(),
navigationController == splitView.navigationController, navigationController == splitView.navigationController,
navigationController.topViewController == viewController else { navigationController.topViewController == viewController else {
NavigationController.setNavigationBarUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) /// Not the split view navigation controller, skip split functions.
return NavigationController.setNavigationBarUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
return
} }
splitView.set(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel, leftPanelAccessible: leftPanelAccessible, rightPanelAccessible: rightPanelAccessible, progress: progress) splitView.set(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel)
} }
/// Sets the navigation item for the view controller based on the model and splitview controller /// Sets the navigation item for the view controller based on the model and splitview controller
private func set(for viewController: UIViewController, navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, leftPanelAccessible: Bool? = nil, rightPanelAccessible: Bool? = nil, progress: Float? = nil) { private func set(for viewController: UIViewController, navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol) {
NavigationController.setNavigationBarUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) NavigationController.setNavigationBarUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
setLeftPanelIsAccessible(leftPanelAccessible ?? leftPanelIsAccessible, for: viewController, updateNavigationButtons: false) setLeftPanelIsAccessible((viewController as? MVMCoreUIDetailViewProtocol)?.isLeftPanelAccessible?() ?? false, for: viewController, updateNavigationButtons: false)
setRightPanelIsAccessible(rightPanelAccessible ?? rightPanelIsAccessible, for: viewController, updateNavigationButtons: false) setRightPanelIsAccessible((viewController as? MVMCoreUIDetailViewProtocol)?.isRightPanelAccessible?() ?? false, for: viewController, updateNavigationButtons: false)
setLeftNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) setLeftNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
setRightNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) setRightNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
setNavigationIconColor(navigationItemModel.tintColor.uiColor) setNavigationIconColor(navigationItemModel.tintColor.uiColor)
if let progress = progress {
setBottomProgressBarProgress(progress)
}
} }
/// Sets the left navigation items for the view controller based on model and splitview. /// Sets the left navigation items for the view controller based on model and splitview.
@ -107,21 +104,4 @@ public extension MVMCoreUISplitViewController {
viewController.navigationItem.setRightBarButtonItems(rightItems.count > 0 ? rightItems : nil, animated: !DisableAnimations.boolValue) viewController.navigationItem.setRightBarButtonItems(rightItems.count > 0 ? rightItems : nil, animated: !DisableAnimations.boolValue)
} }
// MARK: - Legacy Functions
/// Convenience setter for legacy files. Sets the navigation item for the view controller based on the json and splitview controller
@objc static func setNavigationBarUI(for viewController: UIViewController, navigationController: UINavigationController, navigationJSON: [String: Any], leftPanelAccessible: Bool, rightPanelAccessible: Bool, progress: NSNumber?) throws {
let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
guard let navigationItemModel = try MoleculeObjectMapping.shared()?.getMoleculeModelForJSON(navigationJSON, delegateObject: delegate) as? (MoleculeModelProtocol & NavigationItemModelProtocol) else {
throw ModelRegistry.Error.decoderOther(message: "Model not a bar model")
}
guard let splitView = MVMCoreUISplitViewController.main(),
navigationController == splitView.navigationController,
navigationController.topViewController == viewController else {
NavigationController.setNavigationBarUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
return
}
let progress = progress?.floatValue
splitView.set(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel, leftPanelAccessible: leftPanelAccessible, rightPanelAccessible: rightPanelAccessible, progress: progress)
}
} }