From c276b09d7433fb3103e9c606a3337f8beb1e0948 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 2 May 2022 17:39:03 -0400 Subject: [PATCH 1/9] reorganizing defaults --- .../Protocols/MoleculeDelegateProtocol.swift | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/MVMCoreUI/Atomic/Protocols/MoleculeDelegateProtocol.swift b/MVMCoreUI/Atomic/Protocols/MoleculeDelegateProtocol.swift index 1d0a3f61..f2f01b6c 100644 --- a/MVMCoreUI/Atomic/Protocols/MoleculeDelegateProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/MoleculeDelegateProtocol.swift @@ -23,4 +23,33 @@ public protocol MoleculeDelegateProtocol: AnyObject { extension MoleculeDelegateProtocol { public func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { } + + public func getModuleWithName(_ moleculeName: String) -> MoleculeModelProtocol? { + let moduleJSON: [AnyHashable: Any]? = getModuleWithName(moleculeName) + guard let moduleJSON = moduleJSON as? [String: Any], + let moleculeName = moduleJSON.optionalStringForKey("moleculeName"), + let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self) + else { return nil } + + do { + return try modelType.decode(jsonDict: moduleJSON as [String : Any]) as? MoleculeModelProtocol + } catch { + MVMCoreUILoggingHandler.logDebugMessage(withDelegate: "error: \(error)") + } + + return nil + } +} + +extension MoleculeDelegateProtocol where Self: TemplateProtocol { + public func getRootMolecules() -> [MoleculeModelProtocol] { + templateModel?.rootMolecules ?? [] + } +} + +extension MoleculeDelegateProtocol where Self: MVMCoreViewControllerProtocol { + public func getModuleWithName(_ name: String?) -> [AnyHashable : Any]? { + guard let name = name else { return nil } + return loadObject??.modulesJSON?.optionalDictionaryForKey(name) + } } From 35f1cc5c178a0827fdc2c817984351204c547997 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 2 May 2022 17:43:18 -0400 Subject: [PATCH 2/9] template protocol update --- .../Atomic/Protocols/TemplateProtocol.swift | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/MVMCoreUI/Atomic/Protocols/TemplateProtocol.swift b/MVMCoreUI/Atomic/Protocols/TemplateProtocol.swift index 3d1bea9c..06660715 100644 --- a/MVMCoreUI/Atomic/Protocols/TemplateProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/TemplateProtocol.swift @@ -8,43 +8,46 @@ import Foundation -public protocol TemplateProtocol: AnyObject { +public protocol TemplateProtocol: AnyObject, PageProtocol { associatedtype TemplateModel: TemplateModelProtocol var templateModel: TemplateModel? { get set } func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel } -public extension TemplateProtocol where Self: ViewController { +public extension TemplateProtocol { + // Utilize existing underlying property + var templateModel: TemplateModel? { + get { + pageModel as? TemplateModel + } + set { + var mutableSelf = self + mutableSelf.pageModel = newValue + } + } + + /// Helper function to do common parsing logic. func parseTemplate(json: [AnyHashable: Any]?) throws { guard let pageJSON = json else { return } + let delegateObject = (self as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject let data = try JSONSerialization.data(withJSONObject: pageJSON) let decoder = JSONDecoder() - try decoder.add(delegateObject: delegateObjectIVar) + if let delegateObject = delegateObject { + // Add the delegate to access mid parsing if applicable. + try decoder.add(delegateObject: delegateObject) + } templateModel = try decodeTemplate(using: decoder, from: data) - model = templateModel as? MVMControllerModelProtocol - guard let model = model else { return } - traverseAndAddRequiredBehaviors() - var behaviorHandler = self - behaviorHandler.createBehaviors(for: model, delegateObject: delegateObjectIVar) + + // Add additional required behaviors if applicable. + guard var behaviorHandlerModel = templateModel as? TemplateModelProtocol & PageBehaviorHandlerModelProtocol, + var behaviorHandler = self as? PageBehaviorHandlerProtocol else { return } + behaviorHandlerModel.traverseAndAddRequiredBehaviors() + behaviorHandler.createBehaviors(for: behaviorHandlerModel, delegateObject: delegateObject) } func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel { try decoder.decode(TemplateModel.self, from: data) } - - /// Traverses all models and adds any required behavior models. - func traverseAndAddRequiredBehaviors() { - guard var model = model else { return } - let behaviorModels: [PageBehaviorModelProtocol] = model.reduceDepthFirstTraverse(options: .childFirst, depth: 0, initialResult: []) { (accumulator, molecule, depth) in - if let behaviorRequirer = molecule as? PageBehaviorProtocolRequirer { - return accumulator + behaviorRequirer.getRequiredBehaviors() - } - return accumulator - } - for behavior in behaviorModels { - model.add(behavior: behavior) - } - } } From 27f7c223400873b45ad71f7369ab90f6aff38fa8 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 2 May 2022 17:47:25 -0400 Subject: [PATCH 3/9] Change conflicting name TemplateModel to BaseTemplateModel --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ++++---- .../{TemplateModel.swift => BaseTemplateModel.swift} | 4 ++-- MVMCoreUI/Atomic/Templates/CollectionTemplate.swift | 1 - MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift | 4 +--- MVMCoreUI/Atomic/Templates/MoleculeStackTemplate.swift | 1 - MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift | 2 +- MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift | 5 ----- 7 files changed, 8 insertions(+), 17 deletions(-) rename MVMCoreUI/Atomic/Templates/{TemplateModel.swift => BaseTemplateModel.swift} (96%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 0e5dacbb..aa280b9a 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -345,7 +345,7 @@ D22479942316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479932316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift */; }; D22479962316AF6E003FCCF9 /* HeadlineBodyLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479952316AF6D003FCCF9 /* HeadlineBodyLink.swift */; }; D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */; }; - D22D8393241C27B100D3DF69 /* TemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8392241C27B100D3DF69 /* TemplateModel.swift */; }; + D22D8393241C27B100D3DF69 /* BaseTemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8392241C27B100D3DF69 /* BaseTemplateModel.swift */; }; D22D8395241FB41200D3DF69 /* UIStackView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */; }; D23118B325124E18001C8440 /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23118B225124E18001C8440 /* Notification.swift */; }; D2351C7A24A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */; }; @@ -930,7 +930,7 @@ D22479932316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSLayoutConstraintExtension.swift; sourceTree = ""; }; D22479952316AF6D003FCCF9 /* HeadlineBodyLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyLink.swift; sourceTree = ""; }; D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccordionMoleculeTableViewCell.swift; sourceTree = ""; }; - D22D8392241C27B100D3DF69 /* TemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateModel.swift; sourceTree = ""; }; + D22D8392241C27B100D3DF69 /* BaseTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseTemplateModel.swift; sourceTree = ""; }; D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+Extension.swift"; sourceTree = ""; }; D23118B225124E18001C8440 /* Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = ""; }; D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableToggleAllTextAndLinksModel.swift; sourceTree = ""; }; @@ -1969,7 +1969,7 @@ D29DF0DF21E418B2003B2FB9 /* Templates */ = { isa = PBXGroup; children = ( - D22D8392241C27B100D3DF69 /* TemplateModel.swift */, + D22D8392241C27B100D3DF69 /* BaseTemplateModel.swift */, D2092356244FA1EF0044AD09 /* ThreeLayerModelBase.swift */, 014AA72823C5059B006F3E93 /* StackPageTemplateModel.swift */, D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */, @@ -3057,7 +3057,7 @@ D23EA7FE247EBBB700D60C34 /* NavigationLabelButtonModel.swift in Sources */, D28A839123CD4FD400DFE4FC /* CornerLabelsModel.swift in Sources */, 012A88F123985E0100FE3DA1 /* Color.swift in Sources */, - D22D8393241C27B100D3DF69 /* TemplateModel.swift in Sources */, + D22D8393241C27B100D3DF69 /* BaseTemplateModel.swift in Sources */, 012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */, EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */, D23A8FFB26123189007E14CE /* PageBehaviorModelProtocol.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Templates/TemplateModel.swift b/MVMCoreUI/Atomic/Templates/BaseTemplateModel.swift similarity index 96% rename from MVMCoreUI/Atomic/Templates/TemplateModel.swift rename to MVMCoreUI/Atomic/Templates/BaseTemplateModel.swift index 27cb3183..21024474 100644 --- a/MVMCoreUI/Atomic/Templates/TemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/BaseTemplateModel.swift @@ -1,5 +1,5 @@ // -// TemplateModel.swift +// BaseTemplateModel.swift // MVMCoreUI // // Created by Scott Pfeil on 3/13/20. @@ -9,7 +9,7 @@ import Foundation -@objcMembers open class TemplateModel: MVMControllerModelProtocol, TabPageModelProtocol { +@objcMembers open class BaseTemplateModel: MVMControllerModelProtocol, TabPageModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Templates/CollectionTemplate.swift b/MVMCoreUI/Atomic/Templates/CollectionTemplate.swift index f3bd5d83..b1128d8e 100644 --- a/MVMCoreUI/Atomic/Templates/CollectionTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/CollectionTemplate.swift @@ -13,7 +13,6 @@ //-------------------------------------------------- public typealias TemplateModel = CollectionTemplateModel - public var templateModel: CollectionTemplateModel? public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: (CollectionItemModelProtocol & MoleculeModelProtocol))]? diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift index fa404172..d797038d 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift @@ -19,9 +19,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol public var moleculesInfo: [MoleculeInfo]? var observer: NSKeyValueObservation? - - public var templateModel: ListPageTemplateModel? - + //-------------------------------------------------- // MARK: - Computed Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Templates/MoleculeStackTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeStackTemplate.swift index 046469a8..61b247fb 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeStackTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeStackTemplate.swift @@ -15,7 +15,6 @@ open class MoleculeStackTemplate: ThreeLayerViewController, TemplateProtocol { //-------------------------------------------------- var observer: NSKeyValueObservation? - public var templateModel: StackPageTemplateModel? //-------------------------------------------------- // MARK: - Lifecycle diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift index 06d813ef..9f130089 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift @@ -7,7 +7,7 @@ // -@objcMembers open class ThreeLayerModelBase: TemplateModel, ThreeLayerTemplateModelProtocol { +@objcMembers open class ThreeLayerModelBase: BaseTemplateModel, ThreeLayerTemplateModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift index 502b269f..4d1a4a66 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift @@ -9,11 +9,6 @@ import UIKit @objcMembers open class ThreeLayerTemplate: ThreeLayerViewController, TemplateProtocol { - //-------------------------------------------------- - // MARK: - Properties - //-------------------------------------------------- - - public var templateModel: TemplateModel? //-------------------------------------------------- // MARK: - Lifecycle From d1239eda74a60f53a70f5b174b6fe7e7f7ebc5fd Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 2 May 2022 17:50:00 -0400 Subject: [PATCH 4/9] move functions to default --- .../BaseControllers/ViewController.swift | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index d7e947db..26ab983f 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -484,26 +484,6 @@ import UIKit model?.rootMolecules ?? [] } - open func getModuleWithName(_ name: String?) -> [AnyHashable: Any]? { - guard let name = name else { return nil } - return loadObject?.modulesJSON?.optionalDictionaryForKey(name) - } - - open func getModuleWithName(_ moleculeName: String) -> MoleculeModelProtocol? { - guard let moduleJSON = loadObject?.modulesJSON?.optionalDictionaryForKey(moleculeName), - let moleculeName = moduleJSON.optionalStringForKey("moleculeName"), - let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self) - else { return nil } - - do { - return try modelType.decode(jsonDict: moduleJSON) as? MoleculeModelProtocol - } catch { - MVMCoreUILoggingHandler.logDebugMessage(withDelegate: "error: \(error)") - } - - return nil - } - // Needed otherwise when subclassed, the extension gets called. open func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { } @@ -618,12 +598,4 @@ import UIKit selectedField = nil } } - - //-------------------------------------------------- - // MARK: - Behavior Execution - //-------------------------------------------------- - - public func executeBehaviors(_ behaviorBlock: (_ behavior: T) -> Void) { - behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) } - } } From 48388343ef06794a1b9a494135d7d1c0f7d1bc41 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 2 May 2022 17:51:08 -0400 Subject: [PATCH 5/9] Move function for scoping purposes --- .../PageBehaviorHandlerModelProtocol.swift | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerModelProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerModelProtocol.swift index d9b8da9f..bb752694 100644 --- a/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerModelProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerModelProtocol.swift @@ -23,3 +23,19 @@ public extension PageBehaviorHandlerModelProtocol { self.behaviors = newBehaviors } } + +public extension PageBehaviorHandlerModelProtocol where Self: MoleculeTreeTraversalProtocol { + + /// Traverses all models and adds any required behavior models. + mutating func traverseAndAddRequiredBehaviors() { + let behaviorModels: [PageBehaviorModelProtocol] = reduceDepthFirstTraverse(options: .childFirst, depth: 0, initialResult: []) { (accumulator, molecule, depth) in + if let behaviorRequirer = molecule as? PageBehaviorProtocolRequirer { + return accumulator + behaviorRequirer.getRequiredBehaviors() + } + return accumulator + } + for behavior in behaviorModels { + add(behavior: behavior) + } + } +} From 6762082b7c24e248b5c2922bde7d8fd4e0f27715 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 2 May 2022 17:52:15 -0400 Subject: [PATCH 6/9] move function behavior for scoping --- .../Behaviors/Protocols/PageBehaviorHandlerProtocol.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift index eb244cbf..cdabba87 100644 --- a/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift @@ -34,4 +34,9 @@ public extension PageBehaviorHandlerProtocol { } self.behaviors = behaviors.count > 0 ? behaviors : nil } + + /// Executes all behaviors of type. + public func executeBehaviors(_ behaviorBlock: (_ behavior: T) -> Void) { + behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) } + } } From 677c352b9eae42227b3722b08477d868ba4b9014 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 2 May 2022 17:54:37 -0400 Subject: [PATCH 7/9] convenience functions --- .../Behaviors/Protocols/PageBehaviorHandlerProtocol.swift | 2 +- MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift index cdabba87..79f3364f 100644 --- a/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift @@ -36,7 +36,7 @@ public extension PageBehaviorHandlerProtocol { } /// Executes all behaviors of type. - public func executeBehaviors(_ behaviorBlock: (_ behavior: T) -> Void) { + func executeBehaviors(_ behaviorBlock: (_ behavior: T) -> Void) { behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) } } } diff --git a/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift index 3f14f3cc..76bc7f84 100644 --- a/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift @@ -50,8 +50,11 @@ public protocol PageCustomActionHandlerBehavior: PageBehaviorProtocol { } public extension MVMCoreUIDelegateObject { + var behaviorModelDelegate: PageBehaviorHandlerModelProtocol? { + (moleculeDelegate as? PageProtocol)?.pageModel as? PageBehaviorHandlerModelProtocol + } weak var behaviorTemplateDelegate: (PageBehaviorHandlerProtocol & NSObjectProtocol)? { - (moleculeDelegate as? PageProtocol)?.pageModel as? (PageBehaviorHandlerProtocol & NSObjectProtocol) + moleculeDelegate as? (PageBehaviorHandlerProtocol & NSObjectProtocol) } } From b6226616d8ebe465b19d324721c021e57b113a95 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Thu, 5 May 2022 12:33:13 -0400 Subject: [PATCH 8/9] Remove tab bar logic from base controllers and move to the manager. --- .../BaseControllers/ViewController.swift | 43 ------------------- .../MVMCoreUISplitViewController.h | 3 ++ .../MVMCoreUISplitViewController.m | 9 +++- 3 files changed, 11 insertions(+), 44 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 26ab983f..772742b4 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -43,9 +43,6 @@ import UIKit public var selectedField: UIView? - // Stores the previous tab bar index. - public var tabBarIndex: Int? - /// Checks if the screen width has changed open func screenSizeChanged() -> Bool { !MVMCoreGetterUtility.cgfequalwiththreshold(previousScreenSize.width, view.bounds.size.width, 0.1) @@ -244,12 +241,6 @@ import UIKit view.backgroundColor = backgroundColor.uiColor } - // Update splitview properties - if self == MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() { - MVMCoreUISplitViewController.main()?.setBottomProgressBarProgress(bottomProgress() ?? 0) - updateTabBar() - } - // Notify the manager of new data manager?.newDataReceived?(in: self) } @@ -267,34 +258,6 @@ import UIKit return model?.navigationBar } - //-------------------------------------------------- - // MARK: - TabBar - //-------------------------------------------------- - - open func updateTabBar() { - guard MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() == self else { return } - MVMCoreUISplitViewController.main()?.tabBar?.delegateObject = delegateObjectIVar - - if let index = (model as? TabPageModelProtocol)?.tabBarIndex { - MVMCoreUISplitViewController.main()?.tabBar?.highlightTab(at: index) - } else if let index = loadObject?.requestParameters?.actionMap?["tabBarIndex"] as? Int { - MVMCoreUISplitViewController.main()?.tabBar?.highlightTab(at: index) - } else if let index = self.tabBarIndex { - MVMCoreUISplitViewController.main()?.tabBar?.highlightTab(at: index) - } else if let index = MVMCoreUISplitViewController.main()?.tabBar?.currentTabIndex() { - // Store current tab index for cases like back button. - self.tabBarIndex = index - } - - if let hidden = (model as? TabPageModelProtocol)?.tabBarHidden { - MVMCoreUISplitViewController.main()?.updateTabBarShowing(!hidden) - } else if let hidden = loadObject?.requestParameters?.actionMap?["tabBarHidden"] as? Bool { - MVMCoreUISplitViewController.main()?.updateTabBarShowing(!hidden) - } else { - MVMCoreUISplitViewController.main()?.updateTabBarShowing(true) - } - } - //-------------------------------------------------- // MARK: - View Lifecycle //-------------------------------------------------- @@ -349,12 +312,6 @@ import UIKit } open func pageShown() { - // Update split view properties if this is the current detail controller. - if self == MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() { - MVMCoreUISplitViewController.main()?.setBottomProgressBarProgress(bottomProgress() ?? 0) - updateTabBar() - } - // Track. MVMCoreUISession.sharedGlobal()?.currentPageType = pageType MVMCoreUILoggingHandler.shared()?.defaultLogPageState(forController: self) diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h index db5e9cd9..d0530cc9 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h @@ -55,6 +55,9 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) { /// Reference to the tabbar. @property (nullable, weak, nonatomic) UIView *tabBar; +/// Tab bar index history. +@property (nonnull, strong, nonatomic) NSMutableArray *tabBarIndices; + // Convenience getter + (nullable instancetype)mainSplitViewController; diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index 5c337072..e005763b 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -93,13 +93,20 @@ CGFloat const PanelAnimationDuration = 0.2; } - (nullable instancetype)initWithLeftPanel:(nullable UIViewController *)leftPanel rightPanel:(nullable UIViewController *)rightPanel { - if (self = [super init]) { + if (self = [self init]) { self.globalLeftPanel = leftPanel; self.globalRightPanel = rightPanel; } return self; } +- (nullable instancetype)init { + if (self = [super init]) { + self.tabBarIndices = [NSMutableArray array]; + } + return self; +} + #pragma mark - Main Subclassables - (MFNumberOfDrawers)numberOfDrawersShouldShow:(NSNumber *)forWidth { From f2fd2c8d493dfe03766a0157d7e27aa44a77900e Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Thu, 5 May 2022 12:38:32 -0400 Subject: [PATCH 9/9] comments and new functions for setting --- ...MCoreUISplitViewController+Extension.swift | 63 ++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift index 12935302..3c6c878b 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift @@ -12,6 +12,64 @@ import UIKit // Navigation bar update functions public extension MVMCoreUISplitViewController { + /// Updates the state for various controls (navigation, tab, progress) for the controller. + func updateState(with viewController: UIViewController) { + guard let navigationController = navigationController, + navigationController.isDisplayed(viewController: viewController) else { return } + updateNavigationBarFor(viewController: viewController) + updateProgressBar(for: viewController) + updateTabBar(for: viewController) + } + + // MARK: - Progress Bar + /// Updates the progress bar based on the page json for the view controller. + func updateProgressBar(for viewController: UIViewController) { + guard let viewController = viewController as? MVMCoreViewControllerProtocol else { return } + var progress: Float = 0.0 + if let progressString = viewController.loadObject??.pageJSON?.optionalStringForKey(KeyProgressPercent), + let floatValue = Float(progressString) { + progress = floatValue/100 + } + setBottomProgressBarProgress(progress) + } + + // MARK: - Tab Bar + /// Updates the tab bar based on the page json for the view controller. + func updateTabBar(for viewController: UIViewController) { + let mvmViewController = viewController as? MVMCoreViewControllerProtocol + tabBar?.delegateObject = mvmViewController?.delegateObject?() as? MVMCoreUIDelegateObject + + let navigationIndex = (MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController)?.count ?? 1) - 1 + + // Set the highlighted index. In terms of priority, Page > Action > Previous. + if let index = ((viewController as? PageProtocol)?.pageModel as? TabPageModelProtocol)?.tabBarIndex { + tabBar?.highlightTab(at: index) + } else if let index = mvmViewController?.loadObject??.requestParameters?.actionMap?["tabBarIndex"] as? Int { + tabBar?.highlightTab(at: index) + } else if navigationIndex < tabBarIndices.count { + let index = (tabBarIndices[navigationIndex] as! NSNumber).intValue + tabBar?.highlightTab(at: index) + } + + // Store current tab index, so we can switch back when going back in hierarchy. + if tabBarIndices.count > 0 { + tabBarIndices.removeObjects(in: NSRange(location: navigationIndex, length: tabBarIndices.count - navigationIndex)) + } + if let currentIndex = tabBar?.currentTabIndex() { + tabBarIndices.add(NSNumber(integerLiteral: currentIndex)) + } + + // Show/Hide. In terms of priority, Page > Action > Always Show. + if let hidden = ((viewController as? PageProtocol)?.pageModel as? TabPageModelProtocol)?.tabBarHidden { + updateTabBarShowing(!hidden) + } else if let hidden = mvmViewController?.loadObject??.requestParameters?.actionMap?["tabBarHidden"] as? Bool { + updateTabBarShowing(!hidden) + } else { + updateTabBarShowing(true) + } + } + + // MARK: - Navigation Bar /// 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. func setNavigationBar(for viewController: UIViewController, navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol) { guard navigationController == self.navigationController, @@ -122,6 +180,7 @@ public extension MVMCoreUISplitViewController { setStatusBarForCurrentViewController() } + // MARK: - Status Bar /// Returns the bar style for the background color. Light if on a dark background, otherwise default. func getStatusBarStyle(for backgroundColor: UIColor?) -> UIStatusBarStyle { var greyScale: CGFloat = 0 @@ -155,10 +214,10 @@ extension MVMCoreUISplitViewController: MVMCoreViewManagerProtocol { public func willDisplay(_ viewController: UIViewController) { setupPanels() - updateNavigationBarFor(viewController: viewController) + updateState(with: viewController) } public func newDataReceived(in viewController: UIViewController) { - updateNavigationBarFor(viewController: viewController) + updateState(with: viewController) } }