From c1655369a870808f711af05ad3e98f212e02400a Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 21 Apr 2020 15:51:49 -0400 Subject: [PATCH] navigation and template --- MVMCoreUI.xcodeproj/project.pbxproj | 16 ++++- .../NavigationItemModelProtocol.swift | 66 +++++++++---------- .../Templates/ThreeLayerCenterTemplate.swift | 15 +++++ .../ThreeLayerCenterTemplateModel.swift | 15 +++++ .../Atomic/Templates/ThreeLayerTemplate.swift | 4 +- .../Containers/NavigationController.swift | 4 +- ...iewControllerMappingObject+Extension.swift | 29 ++++++++ .../MVMCoreUIViewControllerMappingObject.m | 25 +++---- 8 files changed, 117 insertions(+), 57 deletions(-) create mode 100644 MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplate.swift create mode 100644 MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplateModel.swift create mode 100644 MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject+Extension.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 1b4ab44b..b5d1bf58 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -152,7 +152,7 @@ 9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; }; 943784F5236B77BB006A1E82 /* Wheel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* Wheel.swift */; }; 943784F6236B77BB006A1E82 /* WheelAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* WheelAnimationHandler.swift */; }; - 943820842432382400B43AF3 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943820832432382400B43AF3 /* WebView.swift */; }; + 943820842432382400B43AF3 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943820832432382400B43AF3 /* WebView.swift */; }; 94382086243238D100B43AF3 /* WebViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94382085243238D100B43AF3 /* WebViewModel.swift */; }; 9445890C2385BCE300DE9FD4 /* ProgressBarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */; }; 9445890E2385C3F800DE9FD4 /* MultiProgressModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445890D2385C3F800DE9FD4 /* MultiProgressModel.swift */; }; @@ -224,6 +224,9 @@ C7F8012323E846C300396FBD /* ListRVWheelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7F8012223E846C300396FBD /* ListRVWheelModel.swift */; }; D202AFE4242A5F5E00E5BEDF /* NSTextAlignment+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D202AFE3242A5F5E00E5BEDF /* NSTextAlignment+Extension.swift */; }; D202AFE6242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */; }; + D209234F244F77FD0044AD09 /* ThreeLayerCenterTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D209234E244F77FD0044AD09 /* ThreeLayerCenterTemplate.swift */; }; + D2092351244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2092350244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift */; }; + D2092353244F7D630044AD09 /* MVMCoreUIViewControllerMappingObject+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2092352244F7D630044AD09 /* MVMCoreUIViewControllerMappingObject+Extension.swift */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; D20FB165241A5D75004AFC3A /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */; }; D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; }; @@ -652,6 +655,9 @@ C7F8012223E846C300396FBD /* ListRVWheelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRVWheelModel.swift; sourceTree = ""; }; D202AFE3242A5F5E00E5BEDF /* NSTextAlignment+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSTextAlignment+Extension.swift"; sourceTree = ""; }; D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UICollectionViewScrollPosition+Extension.swift"; sourceTree = ""; }; + D209234E244F77FD0044AD09 /* ThreeLayerCenterTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerCenterTemplate.swift; sourceTree = ""; }; + D2092350244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerCenterTemplateModel.swift; sourceTree = ""; }; + D2092352244F7D630044AD09 /* MVMCoreUIViewControllerMappingObject+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUIViewControllerMappingObject+Extension.swift"; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = ""; }; D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; @@ -1495,6 +1501,8 @@ 942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */, 014AA72A23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift */, D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */, + D2092350244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift */, + D209234E244F77FD0044AD09 /* ThreeLayerCenterTemplate.swift */, D264FAA4243F66A500D98315 /* CollectionTemplateItemProtocol.swift */, D264FA8B243BCD8E00D98315 /* CollectionTemplateModel.swift */, D264FA8D243BCD9A00D98315 /* CollectionTemplate.swift */, @@ -1747,6 +1755,7 @@ D29DF27421E79E81003B2FB9 /* MVMCoreUILoggingHandler.m */, D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */, D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */, + D2092352244F7D630044AD09 /* MVMCoreUIViewControllerMappingObject+Extension.swift */, D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */, ); path = OtherHandlers; @@ -2070,6 +2079,7 @@ AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */, D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */, 0116A4E5228B19640094F3ED /* RadioButtonSelectionHelper.swift in Sources */, + D2092353244F7D630044AD09 /* MVMCoreUIViewControllerMappingObject+Extension.swift in Sources */, 017BEB48236230DB0024EF95 /* MoleculeViewProtocol.swift in Sources */, D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */, 94382086243238D100B43AF3 /* WebViewModel.swift in Sources */, @@ -2106,6 +2116,7 @@ D2E2A98323D8B32D000B42E6 /* EyebrowHeadlineBodyLinkModel.swift in Sources */, 012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */, BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */, + D2092351244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift in Sources */, D21B7F77243BB70700051ABF /* MoleculeCollectionItemModel.swift in Sources */, D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */, 011D9602240DA20A000E3791 /* FormRuleWatcherFieldProtocol.swift in Sources */, @@ -2168,7 +2179,7 @@ D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */, 01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */, D28A838323CCBD3F00DFE4FC /* WheelModel.swift in Sources */, - EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */, + EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */, D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */, DBEFFA04225A829700230692 /* Label.swift in Sources */, D2D6CD4022E78C1A00D701B8 /* Scroller.swift in Sources */, @@ -2195,6 +2206,7 @@ C6FA7D5423C77A4A00A3614A /* NumberedList.swift in Sources */, 0A7ECC702441001C00C828E8 /* UIToolbar+Extension.swift in Sources */, D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */, + D209234F244F77FD0044AD09 /* ThreeLayerCenterTemplate.swift in Sources */, 525019E52406852100EED91C /* ListFourColumnDataUsageDividerModel.swift in Sources */, 0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */, 94FB966323D797DA003D482B /* MFTextButton.m in Sources */, diff --git a/MVMCoreUI/Atomic/Molecules/NavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Molecules/NavigationItemModelProtocol.swift index d7df7cc9..f15a847a 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationItemModelProtocol.swift @@ -10,17 +10,16 @@ import Foundation public protocol NavigationItemModelProtocol { var title: String? { get set } - var titleView: MoleculeModelProtocol? { get set } var hidden: Bool { get set } var backgroundColor: Color? { get set } - var transparent: Bool { get set } + var translucent: Bool { get set } var tintColor: Color { get set } var line: LineModel? { get set } - var systemBackButton: Bool { get set } - var showLeftPanelButton: Bool? { get set } - var showRightPanelButton: Bool? { get set } - var additionalLeftItems: [NavigationItemButtonModel]? { get set } - var additionalRightItems: [NavigationItemButtonModel]? { get set } + var showLeftPanelButton: Bool { get set } + var showRightPanelButton: Bool { get set } + var backButton: NavigationItemButtonModel? { get set } + var additionalLeftButtons: [NavigationItemButtonModel]? { get set } + var additionalRightButtons: [NavigationItemButtonModel]? { get set } } public class NavigationItemButtonModel: Codable { @@ -52,74 +51,73 @@ public class NavigationItemButtonModel: Codable { public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtocol { public class var identifier: String { - return "navigationItem" + return "navigationBar" } public var title: String? - public var titleView: MoleculeModelProtocol? public var hidden: Bool public var backgroundColor: Color? - public var transparent: Bool + public var translucent: Bool public var tintColor: Color public var line: LineModel? - public var systemBackButton = false - public var showLeftPanelButton: Bool? - public var showRightPanelButton: Bool? - public var additionalLeftItems: [NavigationItemButtonModel]? - public var additionalRightItems: [NavigationItemButtonModel]? + public var showLeftPanelButton: Bool + public var showRightPanelButton: Bool + public var backButton: NavigationItemButtonModel? + public var additionalLeftButtons: [NavigationItemButtonModel]? + public var additionalRightButtons: [NavigationItemButtonModel]? - init() { + public init() { hidden = false - transparent = false + translucent = false backgroundColor = Color(uiColor: .white) tintColor = Color(uiColor: .black) line = LineModel(type: .standard) + showLeftPanelButton = true + showRightPanelButton = true + backButton = NavigationItemButtonModel(with: "back", action: ActionBackModel()) } private enum CodingKeys: String, CodingKey { case title - case titleView case hidden case backgroundColor - case transparent + case translucent case tintColor case line - case systemBackButton + case backButton case showLeftPanelButton case showRightPanelButton - case additionalLeftItems - case additionalRightItems + case additionalLeftButtons + case additionalRightButtons } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) title = try typeContainer.decodeIfPresent(String.self, forKey: .title) - titleView = try typeContainer.decodeModelIfPresent(codingKey: .titleView) hidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidden) ?? false backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) ?? Color(uiColor: .white) - transparent = try typeContainer.decodeIfPresent(Bool.self, forKey: .transparent) ?? false + translucent = try typeContainer.decodeIfPresent(Bool.self, forKey: .translucent) ?? false tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .black) line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) - systemBackButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .systemBackButton) ?? false - showLeftPanelButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .showLeftPanelButton) - showRightPanelButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .showRightPanelButton) - additionalLeftItems = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalLeftItems) - additionalRightItems = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalRightItems) + backButton = try typeContainer.decodeIfPresent(NavigationItemButtonModel.self, forKey: .backButton) ?? NavigationItemButtonModel(with: "back", action: ActionBackModel()) + showLeftPanelButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .showLeftPanelButton) ?? true + showRightPanelButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .showRightPanelButton) ?? true + additionalLeftButtons = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalLeftButtons) + additionalRightButtons = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalRightButtons) } open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(title, forKey: .title) - try container.encodeModelIfPresent(titleView, forKey: .titleView) try container.encode(hidden, forKey: .hidden) try container.encode(backgroundColor, forKey: .backgroundColor) - try container.encode(transparent, forKey: .transparent) + try container.encode(translucent, forKey: .translucent) try container.encode(tintColor, forKey: .tintColor) try container.encodeIfPresent(line, forKey: .line) - try container.encode(systemBackButton, forKey: .systemBackButton) + try container.encodeIfPresent(backButton, forKey: .backButton) try container.encode(showLeftPanelButton, forKey: .showLeftPanelButton) try container.encode(showRightPanelButton, forKey: .showRightPanelButton) - try container.encodeIfPresent(additionalLeftItems, forKey: .additionalLeftItems) - try container.encodeIfPresent(additionalRightItems, forKey: .additionalRightItems) + try container.encodeIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons) + try container.encodeIfPresent(additionalRightButtons, forKey: .additionalRightButtons) } } diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplate.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplate.swift new file mode 100644 index 00000000..3d0119a9 --- /dev/null +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplate.swift @@ -0,0 +1,15 @@ +// +// ThreeLayerCenterTemplate.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 4/21/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class ThreeLayerCenterTemplate: ThreeLayerTemplate { + open override func spaceBetweenTopAndMiddle() -> CGFloat? { + return nil + } +} diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplateModel.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplateModel.swift new file mode 100644 index 00000000..4bea76f2 --- /dev/null +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplateModel.swift @@ -0,0 +1,15 @@ +// +// ThreeLayerCenterTemplateModel.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 4/21/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers public class ThreeLayerCenterPageTemplateModel: ThreeLayerPageTemplateModel { + public override class var identifier: String { + return "threeLayerCenter" + } +} diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift index 96e85fad..ae2079d3 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift @@ -8,8 +8,8 @@ import UIKit -@objcMembers open class ThreeLayerTemplate: ThreeLayerViewController, TemplateProtocol { - public var templateModel: ThreeLayerPageTemplateModel? +@objcMembers open class ThreeLayerTemplate: ThreeLayerViewController, TemplateProtocol { + public var templateModel: TemplateModel? open override func parsePageJSON() throws { try parseTemplate(json: loadObject?.pageJSON) diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index eb869e89..03d73240 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -43,10 +43,10 @@ import UIKit public static func set(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) { viewController.navigationItem.title = navigationItemModel.title viewController.navigationItem.accessibilityLabel = navigationItemModel.title - viewController.navigationItem.hidesBackButton = !navigationItemModel.systemBackButton + viewController.navigationItem.hidesBackButton = (navigationItemModel.backButton != nil) navigationController.setNavigationBarHidden(navigationItemModel.hidden, animated: true) - UIColor.setBackgroundColor(navigationItemModel.backgroundColor?.uiColor ?? .white, for: navigationController.navigationBar, isTransparent: navigationItemModel.transparent) + UIColor.setBackgroundColor(navigationItemModel.backgroundColor?.uiColor ?? .white, for: navigationController.navigationBar, isTransparent: navigationItemModel.translucent) let tint = navigationItemModel.tintColor.uiColor navigationController.navigationBar.tintColor = tint diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject+Extension.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject+Extension.swift new file mode 100644 index 00000000..686f6358 --- /dev/null +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject+Extension.swift @@ -0,0 +1,29 @@ +// +// MVMCoreUIViewControllerMappingObject+Extension.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 4/21/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public extension MVMCoreUIViewControllerMappingObject { + func register(template: T.Type) { + add(toTemplateViewControllerMapping: [template.TemplateModel.identifier: MVMCoreViewControllerProgrammaticMappingObject(with: template)!]) + } + + @objc func registerTemplates() { + register(template: MoleculeStackTemplate.self) + register(template: MoleculeStackCenteredTemplate.self) + add(toTemplateViewControllerMapping: ["modalStack": MVMCoreViewControllerProgrammaticMappingObject(with: ModalMoleculeStackTemplate.self)!]) + + register(template: MoleculeListTemplate.self) + add(toTemplateViewControllerMapping: ["modalList": MVMCoreViewControllerProgrammaticMappingObject(with: ModalMoleculeListTemplate.self)!]) + + register(template: ThreeLayerTemplate.self) + register(template: ThreeLayerCenterTemplate.self) + + register(template: CollectionTemplate.self) + } +} diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m index 20fb924e..0ad51d4c 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m @@ -12,23 +12,14 @@ @implementation MVMCoreUIViewControllerMappingObject -- (NSMutableDictionary *)viewControllerMapping { - - // Keeps a mapping of the given page type - static dispatch_once_t onceToken; - static NSMutableDictionary *viewControllerMapping; - dispatch_once(&onceToken, ^{ - viewControllerMapping = [@{ - @"stack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackTemplate class]], - @"centerMoleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackCenteredTemplate class]], - @"list" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeListTemplate class]], - @"threeLayer" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[ThreeLayerTemplate class]], - @"modalStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[ModalMoleculeStackTemplate class]], - @"modalList" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[ModalMoleculeListTemplate class]], - @"collection" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[CollectionTemplate class]] - } mutableCopy]; - }); - return viewControllerMapping; +- (instancetype)init { + if (self = [super init]) { + if (self.viewControllerMapping == nil) { + self.viewControllerMapping = [NSMutableDictionary dictionary]; + } + [self registerTemplates]; + } + return self; } @end