progress bar changes

This commit is contained in:
Panth Patel 2019-06-04 11:52:56 -04:00
commit 458cddb421
48 changed files with 903 additions and 209 deletions

View File

@ -10,9 +10,11 @@
0105618D224BBE7700E1557D /* FormValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618A224BBE7700E1557D /* FormValidator.swift */; }; 0105618D224BBE7700E1557D /* FormValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618A224BBE7700E1557D /* FormValidator.swift */; };
0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */; }; 0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */; };
0105618F224BBE7700E1557D /* FormValidator+FormParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */; }; 0105618F224BBE7700E1557D /* FormValidator+FormParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */; };
016A1071228122180009D605 /* SwitchLineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 016A1070228122180009D605 /* SwitchLineItem.swift */; };
0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0198F79E225679870066C936 /* FormValidationProtocol.swift */; }; 0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0198F79E225679870066C936 /* FormValidationProtocol.swift */; };
0198F7A62256A80B0066C936 /* MFRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 0198F7A02256A80A0066C936 /* MFRadioButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0198F7A62256A80B0066C936 /* MFRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 0198F7A02256A80A0066C936 /* MFRadioButton.h */; settings = {ATTRIBUTES = (Public, ); }; };
0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0198F7A22256A80A0066C936 /* MFRadioButton.m */; }; 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0198F7A22256A80A0066C936 /* MFRadioButton.m */; };
01CA51B5229716F60071A6EE /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01CA51B4229716F60071A6EE /* Switch.swift */; };
01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */; }; 01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */; };
01DF567021FA5AB300CC099B /* TextFieldListFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */; }; 01DF567021FA5AB300CC099B /* TextFieldListFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */; };
01E569D3223FFFA500327251 /* ThreeLayerViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 01E569D3223FFFA500327251 /* ThreeLayerViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; };
@ -35,6 +37,9 @@
D282AACB2243C61700C46919 /* ButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AACA2243C61700C46919 /* ButtonView.swift */; }; D282AACB2243C61700C46919 /* ButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AACA2243C61700C46919 /* ButtonView.swift */; };
D28B4F8A21FF967C00712C7A /* MVMCoreUIObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; D28B4F8A21FF967C00712C7A /* MVMCoreUIObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
D28B4F8B21FF967C00712C7A /* MVMCoreUIObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */; }; D28B4F8B21FF967C00712C7A /* MVMCoreUIObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */; };
D296E13C229598BF0051EBE7 /* MoleculeListCellProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E13B2295969C0051EBE7 /* MoleculeListCellProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
D296E1412295EBBA0051EBE7 /* MoleculeDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E1402295EBBA0051EBE7 /* MoleculeDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
D296E143229729C30051EBE7 /* MoleculeMappingObject+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D296E142229729C30051EBE7 /* MoleculeMappingObject+Extension.swift */; };
D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */; }; D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */; };
D29770C921F7C4AE00B2F0D0 /* TopLabelsView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29770C921F7C4AE00B2F0D0 /* TopLabelsView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */; settings = {ATTRIBUTES = (Public, ); }; };
D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770EE21F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m */; }; D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770EE21F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m */; };
@ -172,9 +177,11 @@
0105618A224BBE7700E1557D /* FormValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidator.swift; sourceTree = "<group>"; }; 0105618A224BBE7700E1557D /* FormValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidator.swift; sourceTree = "<group>"; };
0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+TextFields.swift"; sourceTree = "<group>"; }; 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+TextFields.swift"; sourceTree = "<group>"; };
0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+FormParams.swift"; sourceTree = "<group>"; }; 0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+FormParams.swift"; sourceTree = "<group>"; };
016A1070228122180009D605 /* SwitchLineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwitchLineItem.swift; sourceTree = "<group>"; };
0198F79E225679870066C936 /* FormValidationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidationProtocol.swift; sourceTree = "<group>"; }; 0198F79E225679870066C936 /* FormValidationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidationProtocol.swift; sourceTree = "<group>"; };
0198F7A02256A80A0066C936 /* MFRadioButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFRadioButton.h; sourceTree = "<group>"; }; 0198F7A02256A80A0066C936 /* MFRadioButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFRadioButton.h; sourceTree = "<group>"; };
0198F7A22256A80A0066C936 /* MFRadioButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFRadioButton.m; sourceTree = "<group>"; }; 0198F7A22256A80A0066C936 /* MFRadioButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFRadioButton.m; sourceTree = "<group>"; };
01CA51B4229716F60071A6EE /* Switch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Switch.swift; sourceTree = "<group>"; };
01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MFTextFieldListView.swift; sourceTree = "<group>"; }; 01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MFTextFieldListView.swift; sourceTree = "<group>"; };
01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldListFormViewController.swift; sourceTree = "<group>"; }; 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldListFormViewController.swift; sourceTree = "<group>"; };
B8200E142280C4CF007245F4 /* ProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBar.swift; sourceTree = "<group>"; }; B8200E142280C4CF007245F4 /* ProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBar.swift; sourceTree = "<group>"; };
@ -196,6 +203,9 @@
D282AACA2243C61700C46919 /* ButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonView.swift; sourceTree = "<group>"; }; D282AACA2243C61700C46919 /* ButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonView.swift; sourceTree = "<group>"; };
D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIObject.h; sourceTree = "<group>"; }; D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIObject.h; sourceTree = "<group>"; };
D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIObject.m; sourceTree = "<group>"; }; D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIObject.m; sourceTree = "<group>"; };
D296E13B2295969C0051EBE7 /* MoleculeListCellProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MoleculeListCellProtocol.h; sourceTree = "<group>"; };
D296E1402295EBBA0051EBE7 /* MoleculeDelegateProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MoleculeDelegateProtocol.h; sourceTree = "<group>"; };
D296E142229729C30051EBE7 /* MoleculeMappingObject+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MoleculeMappingObject+Extension.swift"; sourceTree = "<group>"; };
D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsView.m; sourceTree = "<group>"; }; D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsView.m; sourceTree = "<group>"; };
D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TopLabelsView.h; sourceTree = "<group>"; }; D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TopLabelsView.h; sourceTree = "<group>"; };
D29770EE21F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsAndBottomButtonsTableViewController.m; sourceTree = "<group>"; }; D29770EE21F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsAndBottomButtonsTableViewController.m; sourceTree = "<group>"; };
@ -415,6 +425,7 @@
01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */, 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */,
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */, D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */,
D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */, D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */,
D296E13B2295969C0051EBE7 /* MoleculeListCellProtocol.h */,
D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */, D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */,
); );
path = Templates; path = Templates;
@ -446,6 +457,8 @@
D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */, D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */,
D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */, D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */,
D282AACA2243C61700C46919 /* ButtonView.swift */, D282AACA2243C61700C46919 /* ButtonView.swift */,
016A1070228122180009D605 /* SwitchLineItem.swift */,
01CA51B4229716F60071A6EE /* Switch.swift */,
D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */, D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */,
D2A514662213885800345BFB /* StandardHeaderView.swift */, D2A514662213885800345BFB /* StandardHeaderView.swift */,
D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */, D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */,
@ -657,8 +670,10 @@
D29DF27421E79E81003B2FB9 /* MVMCoreUILoggingHandler.m */, D29DF27421E79E81003B2FB9 /* MVMCoreUILoggingHandler.m */,
D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */, D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */,
D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */, D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */,
D296E1402295EBBA0051EBE7 /* MoleculeDelegateProtocol.h */,
D2A514562211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.h */, D2A514562211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.h */,
D2A514572211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m */, D2A514572211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m */,
D296E142229729C30051EBE7 /* MoleculeMappingObject+Extension.swift */,
); );
path = OtherHandlers; path = OtherHandlers;
sourceTree = "<group>"; sourceTree = "<group>";
@ -779,6 +794,7 @@
D29DF12D21E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.h in Headers */, D29DF12D21E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.h in Headers */,
D29DF24E21E6A177003B2FB9 /* MFDigitTextField.h in Headers */, D29DF24E21E6A177003B2FB9 /* MFDigitTextField.h in Headers */,
D29770F321F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.h in Headers */, D29770F321F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.h in Headers */,
D296E1412295EBBA0051EBE7 /* MoleculeDelegateProtocol.h in Headers */,
D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */, D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */,
D29770FD21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h in Headers */, D29770FD21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h in Headers */,
D29DF17421E69E1F003B2FB9 /* MFCustomButton.h in Headers */, D29DF17421E69E1F003B2FB9 /* MFCustomButton.h in Headers */,
@ -787,6 +803,7 @@
D29DF2A121E7AF4E003B2FB9 /* MVMCoreUIUtility.h in Headers */, D29DF2A121E7AF4E003B2FB9 /* MVMCoreUIUtility.h in Headers */,
D29DF17621E69E1F003B2FB9 /* PrimaryButton.h in Headers */, D29DF17621E69E1F003B2FB9 /* PrimaryButton.h in Headers */,
D29DF2C821E7BFC1003B2FB9 /* MFSizeObject.h in Headers */, D29DF2C821E7BFC1003B2FB9 /* MFSizeObject.h in Headers */,
D296E13C229598BF0051EBE7 /* MoleculeListCellProtocol.h in Headers */,
D29DF32021ED0CBA003B2FB9 /* LabelView.h in Headers */, D29DF32021ED0CBA003B2FB9 /* LabelView.h in Headers */,
D29770C921F7C4AE00B2F0D0 /* TopLabelsView.h in Headers */, D29770C921F7C4AE00B2F0D0 /* TopLabelsView.h in Headers */,
D29DF2E121E9240B003B2FB9 /* MVMCoreUIPanelProtocol.h in Headers */, D29DF2E121E9240B003B2FB9 /* MVMCoreUIPanelProtocol.h in Headers */,
@ -920,10 +937,12 @@
D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */, D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */,
D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationController.m in Sources */, D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationController.m in Sources */,
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
D296E143229729C30051EBE7 /* MoleculeMappingObject+Extension.swift in Sources */,
01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */, 01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */,
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */,
D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */, D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */,
D29DF2C721E7BF57003B2FB9 /* MFTabBarInteractor.m in Sources */, D29DF2C721E7BF57003B2FB9 /* MFTabBarInteractor.m in Sources */,
016A1071228122180009D605 /* SwitchLineItem.swift in Sources */,
D29DF29521E7ADB8003B2FB9 /* ProgrammaticScrollViewController.m in Sources */, D29DF29521E7ADB8003B2FB9 /* ProgrammaticScrollViewController.m in Sources */,
D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */, D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */,
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */, D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
@ -943,6 +962,7 @@
D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */, D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */,
D29DF25121E6A177003B2FB9 /* MFDigitTextBox.m in Sources */, D29DF25121E6A177003B2FB9 /* MFDigitTextBox.m in Sources */,
DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */, DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */,
01CA51B5229716F60071A6EE /* Switch.swift in Sources */,
0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */, 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */,
D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */, D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */,
D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */, D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */,

View File

@ -9,6 +9,7 @@
open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol { open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol {
//------------------------------------------------------ //------------------------------------------------------
// MARK: - Constants // MARK: - Constants
//------------------------------------------------------ //------------------------------------------------------
@ -51,6 +52,9 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol {
changeCaretColor() changeCaretColor()
} }
public func updateView(_ size: CGFloat) {
}
//------------------------------------------------------ //------------------------------------------------------
// MARK: - Functions // MARK: - Functions
//------------------------------------------------------ //------------------------------------------------------
@ -110,7 +114,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol {
setTitleColor(disabledColor, for: .disabled) setTitleColor(disabledColor, for: .disabled)
} }
@objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { @objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
setWithActionMap(json, delegateObject: delegateObject, additionalData: additionalData) setWithActionMap(json, delegateObject: delegateObject, additionalData: additionalData)
guard let dictionary = json else { return } guard let dictionary = json else { return }

View File

@ -128,7 +128,7 @@
#pragma mark - MVMCoreUIMoleculeViewProtocol #pragma mark - MVMCoreUIMoleculeViewProtocol
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
NSString *color = [json string:KeyTextColor]; NSString *color = [json string:KeyTextColor];
if (color) { if (color) {
[self setTitleColor:[UIColor mfGetColorForHex:color] forState:UIControlStateNormal]; [self setTitleColor:[UIColor mfGetColorForHex:color] forState:UIControlStateNormal];

View File

@ -648,10 +648,8 @@
[self setAsStandardCustom]; [self setAsStandardCustom];
} }
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol];
[FormValidator setupValidationWithMolecule:self delegate:((MVMCoreUIDelegateObject *)delegateObject).formValidationProtocol];
}
self.primaryButtonType = PrimaryButtonTypeCustom; self.primaryButtonType = PrimaryButtonTypeCustom;
NSString *color = [json string:@"fillColor"]; NSString *color = [json string:@"fillColor"];

View File

@ -116,6 +116,7 @@
- (void)inputFromDatePickerFromDate:(nullable NSDate *)fromDate toDate:(nullable NSDate *)toDate showFromDateAsDefaultInput:(BOOL)show; - (void)inputFromDatePickerFromDate:(nullable NSDate *)fromDate toDate:(nullable NSDate *)toDate showFromDateAsDefaultInput:(BOOL)show;
- (void)setDatePickerFromDate:(nullable NSDate *)fromDate toDate:(nullable NSDate *)toDate; - (void)setDatePickerFromDate:(nullable NSDate *)fromDate toDate:(nullable NSDate *)toDate;
- (nonnull NSDate *)dismissDatePicker; - (nonnull NSDate *)dismissDatePicker;
- (void)dismissPicker;
//get all enabled textfields, can be pairly used with the primary button's handleEnablingWithTextFields if you only want the enable testfield's validation to be tested //get all enabled textfields, can be pairly used with the primary button's handleEnablingWithTextFields if you only want the enable testfield's validation to be tested
+ (nullable NSArray *)getEnabledTextfields:(nullable NSArray <MFTextField *>*)textFieldToDetermine; + (nullable NSArray *)getEnabledTextfields:(nullable NSArray <MFTextField *>*)textFieldToDetermine;

View File

@ -181,6 +181,10 @@
return pickedDate; return pickedDate;
} }
- (void)dismissPicker {
[self.textField resignFirstResponder];
}
- (void)setErrorMessage:(NSString *)errorMessage { - (void)setErrorMessage:(NSString *)errorMessage {
[MVMCoreDispatchUtility performBlockOnMainThread:^{ [MVMCoreDispatchUtility performBlockOnMainThread:^{
@ -559,14 +563,14 @@
self.isMolecule = YES; self.isMolecule = YES;
} }
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) {
[FormValidator setupValidationWithMolecule:self delegate:((MVMCoreUIDelegateObject *)delegateObject).formValidationProtocol]; [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol];
FormValidator *formValidator = [FormValidator getFormValidatorForDelegate:((MVMCoreUIDelegateObject *)delegateObject).formValidationProtocol]; FormValidator *formValidator = [FormValidator getFormValidatorForDelegate:delegateObject.formValidationProtocol];
[self setWithMap:json]; [self setWithMap:json];
self.mfTextFieldDelegate = formValidator; self.mfTextFieldDelegate = formValidator;
self.uiTextFieldDelegate = ((MVMCoreUIDelegateObject *)delegateObject).uiTextFieldDelegate; self.uiTextFieldDelegate = delegateObject.uiTextFieldDelegate;
[MVMCoreUICommonViewsUtility addDismissToolbar:self.textField delegate:self.uiTextFieldDelegate]; [MVMCoreUICommonViewsUtility addDismissToolbar:self.textField delegate:self.uiTextFieldDelegate];
} }
} }

View File

@ -103,7 +103,7 @@ open class CaretView: MFView {
defaultState() defaultState()
} }
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
// Configure class properties with JSON values // Configure class properties with JSON values
guard let dictionary = json else { return } guard let dictionary = json else { return }

View File

@ -68,7 +68,7 @@ open class DashLine: MFView {
isHidden = false isHidden = false
} }
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
// Configure class properties with JSON values // Configure class properties with JSON values

View File

@ -295,7 +295,7 @@ import MVMCore
// MARK: - Atomization // MARK: - Atomization
//------------------------------------------------------ //------------------------------------------------------
@objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { @objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
Label.setUILabel(self, withJSON: json, delegate: delegateObject, additionalData: additionalData) Label.setUILabel(self, withJSON: json, delegate: delegateObject, additionalData: additionalData)
originalAttributedString = attributedText originalAttributedString = attributedText
} }

View File

@ -73,7 +73,7 @@
} }
} }
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
[super setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; [super setWithJSON:json delegateObject:delegateObject additionalData:additionalData];
[self.label setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; [self.label setWithJSON:json delegateObject:delegateObject additionalData:additionalData];
} }

View File

@ -734,7 +734,7 @@ extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol {
} }
@objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { @objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
// Configure class properties with JSON values // Configure class properties with JSON values
guard let dictionary = json else { return } guard let dictionary = json else { return }

View File

@ -197,13 +197,12 @@ import UIKit
if let imageName = json?.optionalStringForKey("image"), shouldLoadImage(withName: imageName, width: width) { if let imageName = json?.optionalStringForKey("image"), shouldLoadImage(withName: imageName, width: width) {
imageView.image = nil imageView.image = nil
imageView.animatedImage = nil imageView.animatedImage = nil
loadImage(withName: imageName, format: json?.optionalStringForKey("imageFormat"), width: NSNumber(value: Double(width)), height: nil)
loadImage(withName: imageName, format: json?.optionalStringForKey("imageFormat"), width: NSNumber(value: Double(width)), height: nil, customFallbackImage: json?.optionalStringForKey("fallbackImage")) loadImage(withName: imageName, format: json?.optionalStringForKey("imageFormat"), width: NSNumber(value: Double(width)), height: nil, customFallbackImage: json?.optionalStringForKey("fallbackImage"))
} }
} }
// MARK: - MVMCoreUIMoleculeViewProtocol functions // MARK: - MVMCoreUIMoleculeViewProtocol functions
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) { if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) {
backgroundColor = UIColor.mfGet(forHex: backgroundColorString) backgroundColor = UIColor.mfGet(forHex: backgroundColorString)

View File

@ -44,7 +44,7 @@
#pragma mark - MVMCoreUIMoleculeViewProtocol #pragma mark - MVMCoreUIMoleculeViewProtocol
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
self.json = json; self.json = json;
} }

View File

@ -58,9 +58,9 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
return UIStackViewAlignmentLeading; return UIStackViewAlignmentLeading;
} }
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
[FormValidator setupValidationWithMolecule:self delegate:((MVMCoreUIDelegateObject *)delegateObject).formValidationProtocol]; [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol];
self.delegate = delegateObject; self.delegate = delegateObject;
self.fieldKey = [json stringForKey:KeyFieldKey]; self.fieldKey = [json stringForKey:KeyFieldKey];
self.isRequired = [json boolForKey:KeyRequired]; self.isRequired = [json boolForKey:KeyRequired];
@ -342,8 +342,10 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
[self.checkMark updateCheckSelected:NO animated:animated]; [self.checkMark updateCheckSelected:NO animated:animated];
} }
FormValidator *formValidator = ((MVMCoreUIDelegateObject *)self.delegate).formValidationProtocol.formValidatorModel; if (self.delegate && [self.delegate respondsToSelector:@selector(formValidationProtocol)] && [[self.delegate performSelector:@selector(formValidationProtocol)] respondsToSelector:@selector(formValidatorModel)]) {
[formValidator enableByValidation]; FormValidator *formValidator = [[self.delegate performSelector:@selector(formValidationProtocol)] performSelector:@selector(formValidatorModel)];
[formValidator enableByValidation];
}
} }
- (void)setColor:(nullable UIColor *)color forState:(UIControlState)state { - (void)setColor:(nullable UIColor *)color forState:(UIControlState)state {

View File

@ -95,17 +95,21 @@
} }
} }
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
[super setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; [super setWithJSON:json delegateObject:delegateObject additionalData:additionalData];
if (json) { if (json) {
self.hidden = NO;
NSString *type = [json string:KeyType]; NSString *type = [json string:KeyType];
if ([type isEqualToString:@"standard"]) { if ([type isEqualToString:@"none"]) {
[self setSize:1]; self.hidden = YES;
} else if ([type isEqualToString:@"medium"]) { } else {
[self setSize:2]; self.hidden = NO;
} else if ([type isEqualToString:@"heavy"]) { if ([type isEqualToString:@"medium"]) {
[self setSize:4]; [self setAsMedium];
} else if ([type isEqualToString:@"heavy"]) {
[self setAsHeavy];
} else {
[self setAsLight];
}
} }
NSString *backgroundColor = [json string:KeyBackgroundColor]; NSString *backgroundColor = [json string:KeyBackgroundColor];
if (backgroundColor) { if (backgroundColor) {

View File

@ -151,7 +151,7 @@
self.updateViewHorizontalDefaults = YES; self.updateViewHorizontalDefaults = YES;
} }
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
[super setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; [super setWithJSON:json delegateObject:delegateObject additionalData:additionalData];
if (self.molecule) { if (self.molecule) {
[self.molecule setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; [self.molecule setWithJSON:json delegateObject:delegateObject additionalData:additionalData];

View File

@ -27,13 +27,14 @@
#import <MVMCoreUI/ButtonDelegateProtocol.h> #import <MVMCoreUI/ButtonDelegateProtocol.h>
#import <MVMCoreUI/MFStyler.h> #import <MVMCoreUI/MFStyler.h>
#import <MVMCoreUI/MVMCoreUIDetailViewProtocol.h> #import <MVMCoreUI/MVMCoreUIDetailViewProtocol.h>
#import <MVMCoreUI/MoleculeDelegateProtocol.h>
@class MainMenuViewController; @class MainMenuViewController;
@class MVMCoreUITabBarPageControlViewController; @class MVMCoreUITabBarPageControlViewController;
@class MVMAnimationManager; @class MVMAnimationManager;
@class DelegateObject; @class DelegateObject;
@interface MFViewController : UIViewController <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol, MVMCoreActionDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, MFTextFieldDelegate, ButtonDelegateProtocol, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MVMCoreUIDetailViewProtocol> @interface MFViewController : UIViewController <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol, MVMCoreActionDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, MFTextFieldDelegate, ButtonDelegateProtocol, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MVMCoreUIDetailViewProtocol, MoleculeDelegateProtocol>
// Stores the load object that this screen was loaded with. // Stores the load object that this screen was loaded with.
@property (nullable, strong, nonatomic) MVMCoreLoadObject *loadObject; @property (nullable, strong, nonatomic) MVMCoreLoadObject *loadObject;

View File

@ -279,7 +279,7 @@
- (void)updateNavigationBarUI:(nonnull UINavigationController *)navigationController { - (void)updateNavigationBarUI:(nonnull UINavigationController *)navigationController {
if (navigationController) { if (navigationController) {
[navigationController setNavigationBarHidden:[self navigationBarHidden] animated:NO]; [navigationController setNavigationBarHidden:[self navigationBarHidden] animated:YES];
[UIColor mfSetBackgroundColorForNavigationBar:[self navigationBarColor] navigationBar:navigationController.navigationBar transparent:[self navigationBarTransparent]]; [UIColor mfSetBackgroundColorForNavigationBar:[self navigationBarColor] navigationBar:navigationController.navigationBar transparent:[self navigationBarTransparent]];
@ -297,6 +297,7 @@
if (navigationController == [MVMCoreUISplitViewController mainSplitViewController].navigationController) { if (navigationController == [MVMCoreUISplitViewController mainSplitViewController].navigationController) {
// Update icons if main navigation controller. // Update icons if main navigation controller.
[[MVMCoreUISession sharedGlobal].splitViewController setupPanels];
[self setMasterShouldBeAccessible:self.masterShouldBeAccessible]; [self setMasterShouldBeAccessible:self.masterShouldBeAccessible];
[self setSupportShouldBeAccessible:self.supportShouldBeAccessible]; [self setSupportShouldBeAccessible:self.supportShouldBeAccessible];
[self showBottomProgressBar]; [self showBottomProgressBar];
@ -343,15 +344,24 @@
- (BOOL)isOverridingRightButton { - (BOOL)isOverridingRightButton {
NSDictionary *rightPanelLinkDict = [self.loadObject.pageJSON dict:@"rightPanelButtonLink"]; NSDictionary *rightPanelLinkDict = [self.loadObject.pageJSON dict:@"rightPanelButtonLink"];
if (rightPanelLinkDict) { if (rightPanelLinkDict) {
[[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:rightPanelLinkDict [[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:rightPanelLinkDict additionalData:nil delegateObject:[self delegateObject]];
additionalData:nil
delegateObject:[self delegateObject]];
return YES; return YES;
} else { } else {
return NO; return NO;
} }
} }
- (BOOL)isOverridingLeftButton {
NSDictionary *leftPanelLinkDict = [self.loadObject.pageJSON dict:@"leftPanelButtonLink"];
if (leftPanelLinkDict) {
[[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:leftPanelLinkDict additionalData:nil delegateObject:[self delegateObject]];
return YES;
} else {
return NO;
}
}
- (void)setSupportShouldBeAccessible:(BOOL)supportShouldBeAccessible { - (void)setSupportShouldBeAccessible:(BOOL)supportShouldBeAccessible {
MVMCoreUISplitViewController *splitViewController = [MVMCoreUISession sharedGlobal].splitViewController; MVMCoreUISplitViewController *splitViewController = [MVMCoreUISession sharedGlobal].splitViewController;
@ -777,6 +787,15 @@
} }
} }
#pragma mark - MoleculeDelegateProtocol
- (NSDictionary *)getModuleWithName:(NSString *)name {
if (!name) {
return nil;
}
return [self.loadObject.modulesJSON dict:name];
}
#pragma mark - adobe analytics #pragma mark - adobe analytics
- (nullable NSArray <NSDictionary *> *)additionalActionsToTrackWithMainActionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData { - (nullable NSArray <NSDictionary *> *)additionalActionsToTrackWithMainActionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData {

View File

@ -21,6 +21,12 @@ NS_ASSUME_NONNULL_BEGIN
- (void)panelWillDisappear:(nonnull NSObject <MVMCoreUIPanelProtocol>*)panel; - (void)panelWillDisappear:(nonnull NSObject <MVMCoreUIPanelProtocol>*)panel;
- (void)panelDidDisappear:(nonnull NSObject <MVMCoreUIPanelProtocol>*)panel; - (void)panelDidDisappear:(nonnull NSObject <MVMCoreUIPanelProtocol>*)panel;
/// Can override the left panel.
- (nullable UIViewController <MVMCoreUIPanelProtocol>*)overrideLeftPanel;
/// Can override the right panel.
- (nullable UIViewController <MVMCoreUIPanelProtocol>*)overrideRightPanel;
// Called when the back button is pressed. Overwrite for special functionality. // Called when the back button is pressed. Overwrite for special functionality.
- (void)backButtonPressed; - (void)backButtonPressed;

View File

@ -6,7 +6,7 @@
// Copyright © 2017 Verizon Wireless. All rights reserved. // Copyright © 2017 Verizon Wireless. All rights reserved.
// //
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h>
@protocol MVMCoreUIPanelProtocol <NSObject> @protocol MVMCoreUIPanelProtocol <NSObject>
#pragma mark - life cycle #pragma mark - life cycle
@ -33,6 +33,12 @@
- (void)showArrow; - (void)showArrow;
- (void)hideArrow; - (void)hideArrow;
/// The width to use if the panel is automatically extended when the screen is big enough.
- (CGFloat)panelExtendedWidth;
/// The maximum width of the panel.
- (CGFloat)panelMaxWidth;
// Gets called when we are restarting or clearing a session. // Gets called when we are restarting or clearing a session.
- (void)clearData; - (void)clearData;

View File

@ -80,6 +80,9 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
// contains speicaly logic to set the icon color // contains speicaly logic to set the icon color
- (void)setNavigationIconColor:(nullable UIColor *)color; - (void)setNavigationIconColor:(nullable UIColor *)color;
/// Updates the panels that are used.
- (void)setupPanels;
#pragma mark - Bottom Progress Bar #pragma mark - Bottom Progress Bar
- (void)setBottomProgressBarProgress:(float)progress; - (void)setBottomProgressBarProgress:(float)progress;
@ -114,7 +117,7 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
// Can subclass to set threshold for when the drawers are permanently extended. Default is 1000 for the left panel and 2000 for both. // Can subclass to set threshold for when the drawers are permanently extended. Default is 1000 for the left panel and 2000 for both.
- (MFNumberOfDrawers)numberOfDrawersShouldShow:(nullable NSNumber *)forWidth; - (MFNumberOfDrawers)numberOfDrawersShouldShow:(nullable NSNumber *)forWidth;
// subclass to return panels // subclass to return default global panels. kept alive after creation.
- (nullable UIViewController <MVMCoreUIPanelProtocol> *)createLeftPanelViewController; - (nullable UIViewController <MVMCoreUIPanelProtocol> *)createLeftPanelViewController;
- (nullable UIViewController <MVMCoreUIPanelProtocol> *)createRightPanelViewController; - (nullable UIViewController <MVMCoreUIPanelProtocol> *)createRightPanelViewController;

View File

@ -27,6 +27,12 @@
@interface MVMCoreUISplitViewController () @interface MVMCoreUISplitViewController ()
typedef NS_OPTIONS(NSInteger, MFExtendedDrawer) {
MFExtendedDrawerNone = 0,
MFExtendedDrawerRight,
MFExtendedDrawerLeft
};
@property (weak, nonatomic) UIView *leftView; @property (weak, nonatomic) UIView *leftView;
@property (weak, nonatomic) UIView *mainView; @property (weak, nonatomic) UIView *mainView;
@property (weak, nonatomic) UIView *rightView; @property (weak, nonatomic) UIView *rightView;
@ -38,6 +44,10 @@
@property (weak, nonatomic) UIView *leftPanelSeparator; @property (weak, nonatomic) UIView *leftPanelSeparator;
@property (weak, nonatomic) UIView *rightPanelSeparator; @property (weak, nonatomic) UIView *rightPanelSeparator;
// For keeping
@property (strong, nonatomic, readwrite) UIViewController <MVMCoreUIPanelProtocol> *globalLeftPanel;
@property (strong, nonatomic, readwrite) UIViewController <MVMCoreUIPanelProtocol> *globalRightPanel;
@property (weak, nonatomic, readwrite) UIViewController <MVMCoreUIPanelProtocol> *leftPanel; @property (weak, nonatomic, readwrite) UIViewController <MVMCoreUIPanelProtocol> *leftPanel;
@property (weak, nonatomic, readwrite) UIViewController <MVMCoreUIPanelProtocol> *rightPanel; @property (weak, nonatomic, readwrite) UIViewController <MVMCoreUIPanelProtocol> *rightPanel;
@property (weak, nonatomic, readwrite) MVMCoreUINavigationController *navigationController; @property (weak, nonatomic, readwrite) MVMCoreUINavigationController *navigationController;
@ -51,13 +61,7 @@
@property (nonatomic, strong) UIGestureRecognizer *tapToDismissGesture; @property (nonatomic, strong) UIGestureRecognizer *tapToDismissGesture;
@property (nullable, readwrite, weak, nonatomic) NSObject <MVMCoreUIPanelProtocol> *explictlyShowingPanel; @property (nullable, readwrite, weak, nonatomic) NSObject <MVMCoreUIPanelProtocol> *explictlyShowingPanel;
@property (nullable, weak, nonatomic) NSObject <MVMCoreUIPanelProtocol> *prioritizedExtendedPanel; @property (nonatomic) MFExtendedDrawer prioritizedExtendedPanel;
typedef NS_OPTIONS(NSInteger, MFExtendedDrawer) {
MFExtendedDrawerNone = 0,
MFExtendedDrawerRight,
MFExtendedDrawerLeft
};
@property (nonatomic) MFExtendedDrawer extendedDrawers; @property (nonatomic) MFExtendedDrawer extendedDrawers;
@property (nonatomic, readwrite) BOOL leftPanelIsAccessible; @property (nonatomic, readwrite) BOOL leftPanelIsAccessible;
@ -119,18 +123,30 @@ CGFloat const PanelAnimationDuration = 0.2;
} }
- (CGFloat)leftPanelExtendedWidth { - (CGFloat)leftPanelExtendedWidth {
if ([self.leftPanel respondsToSelector:@selector(panelExtendedWidth)]) {
return [self.leftPanel panelExtendedWidth];
}
return 320; return 320;
} }
- (CGFloat)leftPanelMaxWidth { - (CGFloat)leftPanelMaxWidth {
if ([self.leftPanel respondsToSelector:@selector(panelMaxWidth)]) {
return [self.leftPanel panelMaxWidth];
}
return 415; return 415;
} }
- (CGFloat)rightPanelExtendedWidth { - (CGFloat)rightPanelExtendedWidth {
if ([self.rightPanel respondsToSelector:@selector(panelExtendedWidth)]) {
return [self.rightPanel panelExtendedWidth];
}
return 320; return 320;
} }
- (CGFloat)rightPanelMaxWidth { - (CGFloat)rightPanelMaxWidth {
if ([self.rightPanel respondsToSelector:@selector(panelMaxWidth)]) {
return [self.rightPanel panelMaxWidth];
}
return 500; return 500;
} }
@ -217,7 +233,7 @@ CGFloat const PanelAnimationDuration = 0.2;
return NO; return NO;
} else { } else {
// left is extended if the right panel isn't prioritized. // left is extended if the right panel isn't prioritized.
return self.prioritizedExtendedPanel != self.rightPanel; return self.prioritizedExtendedPanel != MFExtendedDrawerRight;
} }
} }
} }
@ -420,7 +436,7 @@ CGFloat const PanelAnimationDuration = 0.2;
return NO; return NO;
} else { } else {
// Extend right if the left panel isn't prioritized. // Extend right if the left panel isn't prioritized.
return self.prioritizedExtendedPanel != self.leftPanel; return self.prioritizedExtendedPanel != MFExtendedDrawerLeft;
} }
} }
} }
@ -656,6 +672,98 @@ CGFloat const PanelAnimationDuration = 0.2;
} }
} }
- (void)addPanel:(nonnull UIViewController <MVMCoreUIPanelProtocol> *)panel {
UIView *view = panel.view;
[self addChildViewController:panel];
[self.view addSubview:view];
[panel didMoveToParentViewController:self];
}
- (void)removePanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)panel {
[panel willMoveToParentViewController:nil];
[panel.view removeFromSuperview];
[panel removeFromParentViewController];
}
- (void)setupLeftPanel {
UIViewController <MVMCoreUIPanelProtocol> *panel = nil;
UIViewController *currentViewController = [self getCurrentDetailViewController];
if ([currentViewController respondsToSelector:@selector(overrideLeftPanel)]) {
panel = [((UIViewController <MVMCoreUIDetailViewProtocol> *)currentViewController) overrideLeftPanel];
} else {
panel = self.globalLeftPanel;
self.leftPanelButton = nil;
}
if (!panel) {
[self removePanel:self.leftPanel];
} else if (panel && panel != self.leftPanel) {
[self removePanel:self.leftPanel];
[self addPanel:panel];
self.leftView = panel.view;
self.leftPanel = panel;
self.leftView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *leftPanelWidth = [NSLayoutConstraint constraintWithItem:self.leftView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:270];
self.leftView.translatesAutoresizingMaskIntoConstraints = NO;
leftPanelWidth.active = YES;
self.leftPanelWidth = leftPanelWidth;
[NSLayoutConstraint constraintWithItem:self.mainView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.leftView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:self.leftView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:self.leftView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES;
if ([panel respondsToSelector:@selector(buttonForPanel)]) {
self.leftPanelButton = [panel buttonForPanel];
} else if ([panel respondsToSelector:@selector(imageForButtonForPanel)]) {
self.leftPanelButton = [[UIBarButtonItem alloc] initWithImage:[panel imageForButtonForPanel] style:UIBarButtonItemStylePlain target:self action:@selector(leftPanelButtonPressed:)];
} else {
self.leftPanelButton = nil;
}
}
}
- (void)setupRightPanel {
UIViewController <MVMCoreUIPanelProtocol> *panel = nil;
UIViewController *currentViewController = [self getCurrentDetailViewController];
if ([currentViewController respondsToSelector:@selector(overrideRightPanel)]) {
panel = [((UIViewController <MVMCoreUIDetailViewProtocol> *)currentViewController) overrideRightPanel];
} else {
panel = self.globalRightPanel;
}
if (!panel) {
[self removePanel:self.rightPanel];
self.rightPanelButton = nil;
} else if (panel && panel != self.rightPanel) {
[self removePanel:self.rightPanel];
[self addPanel:panel];
self.rightView = panel.view;
self.rightPanel = panel;
self.rightView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *rightPanelWidth = [NSLayoutConstraint constraintWithItem:self.rightView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:270];
rightPanelWidth.active = YES;
self.rightPanelWidth = rightPanelWidth;
[NSLayoutConstraint constraintWithItem:self.rightView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:self.rightView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:self.rightView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES;
if ([panel respondsToSelector:@selector(buttonForPanel)]) {
self.rightPanelButton = [panel buttonForPanel];
} else if ([panel respondsToSelector:@selector(imageForButtonForPanel)]) {
self.rightPanelButton = [[UIBarButtonItem alloc] initWithImage:[panel imageForButtonForPanel] style:UIBarButtonItemStylePlain target:self action:@selector(rightPanelButtonPressed:)];
} else {
self.rightPanelButton = nil;
}
}
}
- (void)setupPanels {
[self forceHideBothDrawers];
[self setupLeftPanel];
[self setupRightPanel];
self.explictlyShowingPanel = nil;
[self.view layoutIfNeeded];
}
#pragma mark - Bottom Progress Bar #pragma mark - Bottom Progress Bar
- (void)setBottomProgressBarProgress:(float)progress { - (void)setBottomProgressBarProgress:(float)progress {
@ -744,62 +852,16 @@ CGFloat const PanelAnimationDuration = 0.2;
[NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES; [NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES; [NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES;
// Left Panel // Create panels
UIViewController <MVMCoreUIPanelProtocol> *leftPanel = [self createLeftPanelViewController]; self.globalLeftPanel = [self createLeftPanelViewController];
if (leftPanel) { self.globalRightPanel = [self createRightPanelViewController];
UIView *leftView = leftPanel.view; [self setupPanels];
[self addChildViewController:leftPanel];
[self.view addSubview:leftView];
[leftPanel didMoveToParentViewController:self];
self.leftView = leftView;
self.leftPanel = leftPanel;
NSLayoutConstraint *leftPanelWidth = [NSLayoutConstraint constraintWithItem:leftView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:270];
leftPanelWidth.active = YES;
self.leftPanelWidth = leftPanelWidth;
[NSLayoutConstraint constraintWithItem:mainView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:leftView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:leftView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:leftView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES;
}
// Right Panel
UIViewController <MVMCoreUIPanelProtocol> *rightPanel = [self createRightPanelViewController];
if (rightPanel) {
UIView *rightView = rightPanel.view;
[self addChildViewController:rightPanel];
[self.view addSubview:rightView];
[rightPanel didMoveToParentViewController:self];
self.rightView = rightView;
self.rightPanel = rightPanel;
NSLayoutConstraint *rightPanelWidth = [NSLayoutConstraint constraintWithItem:rightView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:270];
rightPanelWidth.active = YES;
self.rightPanelWidth = rightPanelWidth;
[NSLayoutConstraint constraintWithItem:rightView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:rightView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:rightView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES;
}
} }
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
[self.topAlertView pinATopViewController:self]; [self.topAlertView pinATopViewController:self];
// Do any additional setup after loading the view.
if (self.leftPanel) {
if ([self.leftPanel respondsToSelector:@selector(buttonForPanel)]) {
self.leftPanelButton = [self.leftPanel buttonForPanel];
} else {
self.leftPanelButton = [[UIBarButtonItem alloc] initWithImage:[self.leftPanel imageForButtonForPanel] style:UIBarButtonItemStylePlain target:self action:@selector(leftPanelButtonPressed:)];
}
}
if (self.rightPanel) {
if ([self.rightPanel respondsToSelector:@selector(buttonForPanel)]) {
self.rightPanelButton = [self.rightPanel buttonForPanel];
} else {
self.rightPanelButton = [[UIBarButtonItem alloc] initWithImage:[self.rightPanel imageForButtonForPanel] style:UIBarButtonItemStylePlain target:self action:@selector(rightPanelButtonPressed:)];
}
}
// Creates the back button // Creates the back button
self.backButton = [[UIBarButtonItem alloc] initWithImage:[self imageForBackButton] style:UIBarButtonItemStylePlain target:self action:@selector(backButtonPressed:)]; self.backButton = [[UIBarButtonItem alloc] initWithImage:[self imageForBackButton] style:UIBarButtonItemStylePlain target:self action:@selector(backButtonPressed:)];
self.backButton.imageInsets = UIEdgeInsetsMake(0, 4, 0, -8); self.backButton.imageInsets = UIEdgeInsetsMake(0, 4, 0, -8);
@ -811,7 +873,7 @@ CGFloat const PanelAnimationDuration = 0.2;
} }
self.extendedDrawers = MFExtendedDrawerLeft | MFExtendedDrawerRight; self.extendedDrawers = MFExtendedDrawerLeft | MFExtendedDrawerRight;
self.prioritizedExtendedPanel = self.leftPanel; self.prioritizedExtendedPanel = MFExtendedDrawerLeft;
self.view.backgroundColor = [UIColor blackColor]; self.view.backgroundColor = [UIColor blackColor];
} }

View File

@ -139,6 +139,22 @@
} }
} }
- (BOOL)isOverridingLeftButton {
if ([self.viewController respondsToSelector:@selector(isOverridingLeftButton)]) {
return [self.viewController performSelector:@selector(isOverridingLeftButton)];
} else {
return [super isOverridingLeftButton];
}
}
- (BOOL)isOverridingRightButton {
if ([self.viewController respondsToSelector:@selector(isOverridingRightButton)]) {
return [self.viewController performSelector:@selector(isOverridingRightButton)];
} else {
return [super isOverridingRightButton];
}
}
#pragma mark - View Cycle #pragma mark - View Cycle
- (void)loadView { - (void)loadView {

View File

@ -20,6 +20,8 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[];
#import <MVMCoreUI/MVMCoreUISession.h> #import <MVMCoreUI/MVMCoreUISession.h>
#import <MVMCoreUI/MVMCoreUILoggingHandler.h> #import <MVMCoreUI/MVMCoreUILoggingHandler.h>
#import <MVMCoreUI/MVMCoreUIViewControllerMappingObject.h> #import <MVMCoreUI/MVMCoreUIViewControllerMappingObject.h>
#import <MVMCoreUI/MoleculeDelegateProtocol.h>
#import <MVMCoreUI/MoleculeListCellProtocol.h>
#import <MVMCoreUI/MVMCoreUIMoleculeMappingObject.h> #import <MVMCoreUI/MVMCoreUIMoleculeMappingObject.h>
#pragma mark - TopAlert #pragma mark - TopAlert

View File

@ -33,7 +33,7 @@ import UIKit
primaryButton?.isEnabled = enabled primaryButton?.isEnabled = enabled
} }
public init(withJSON json: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) { public init(withJSON json: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) {
super.init(frame: .zero) super.init(frame: .zero)
setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
} }
@ -58,11 +58,15 @@ import UIKit
primaryButton?.setAsMolecule() primaryButton?.setAsMolecule()
} }
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
primaryButton?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) primaryButton?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
} }
public override static func estimatedHeight(forRow json: [AnyHashable : Any]?) -> CGFloat {
return 42
}
// MARK: - Constraining // MARK: - Constraining
func setupButton() { func setupButton() {
if let primaryButton = primaryButton, !subviews.contains(primaryButton) { if let primaryButton = primaryButton, !subviews.contains(primaryButton) {

View File

@ -7,12 +7,13 @@
// //
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
@class DelegateObject; @import MVMCore.MVMCoreViewProtocol;
@class MVMCoreUIDelegateObject;
@protocol MVMCoreUIMoleculeViewProtocol <NSObject> @protocol MVMCoreUIMoleculeViewProtocol <NSObject, MVMCoreViewProtocol>
// Sets up the ui based on the json // Sets up the ui based on the json
- (void)setWithJSON:(nullable NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; - (void)setWithJSON:(nullable NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData;
@optional @optional
@ -26,7 +27,7 @@
- (UIStackViewAlignment)moleculeAlignment; - (UIStackViewAlignment)moleculeAlignment;
// For the molecule list to load more efficiently. // For the molecule list to load more efficiently.
+ (CGFloat)estimatedHeightForRow; + (CGFloat)estimatedHeightForRow:(nullable NSDictionary *)json;
@end @end

View File

@ -18,12 +18,12 @@ public class MoleculeStackView: MFView {
super.init(frame: frame) super.init(frame: frame)
} }
public init(withJSON json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) { public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
super.init(frame: CGRect.zero) super.init(frame: CGRect.zero)
setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
} }
public convenience init(withJSON json: [AnyHashable: Any]?, delegateObject: DelegateObject?, spacingBlock: ((Any) -> UIEdgeInsets)?) { public convenience init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, spacingBlock: ((Any) -> UIEdgeInsets)?) {
self.init(withJSON: json, delegateObject: delegateObject, additionalData: nil) self.init(withJSON: json, delegateObject: delegateObject, additionalData: nil)
self.spacingBlock = spacingBlock self.spacingBlock = spacingBlock
} }
@ -51,7 +51,7 @@ public class MoleculeStackView: MFView {
} }
// MARK: - MVMCoreUIMoleculeViewProtocol // MARK: - MVMCoreUIMoleculeViewProtocol
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
guard let molecules = json?.arrayForKey(KeyMolecules) as? [[String: Any]] else { guard let molecules = json?.arrayForKey(KeyMolecules) as? [[String: Any]] else {
return return
@ -60,7 +60,7 @@ public class MoleculeStackView: MFView {
// Create the molecules and set the json. // Create the molecules and set the json.
var moleculesArray = [] as [UIView] var moleculesArray = [] as [UIView]
for moleculeJSON in molecules { for moleculeJSON in molecules {
if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject) { if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: true) {
moleculesArray.append(molecule) moleculesArray.append(molecule)
} }
} }

View File

@ -8,8 +8,10 @@
import UIKit import UIKit
@objcMembers open class MoleculeTableViewCell: UITableViewCell, MVMCoreViewProtocol, MVMCoreUIMoleculeViewProtocol { @objcMembers open class MoleculeTableViewCell: UITableViewCell, MVMCoreUIMoleculeViewProtocol, MoleculeListCellProtocol {
open var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)? open var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)?
open var json: [AnyHashable: Any]?
// For the accessory view convenience. // For the accessory view convenience.
public var caretView: CaretView? public var caretView: CaretView?
@ -50,9 +52,7 @@ import UIKit
bottomSeparatorView?.setLeftAndRightPinConstant(layoutMargins.left) bottomSeparatorView?.setLeftAndRightPinConstant(layoutMargins.left)
} }
if let molecule = molecule as? MVMCoreViewProtocol { molecule?.updateView(size)
molecule.updateView(size)
}
if let _ = accessoryView, let caretView = caretView, let widthObject = caretViewWidthSizeObject, let heightObject = caretViewHeightSizeObject { if let _ = accessoryView, let caretView = caretView, let widthObject = caretViewWidthSizeObject, let heightObject = caretViewHeightSizeObject {
caretView.frame = CGRect(x: 0, y: 0, width: widthObject.getValueBased(onSize: size), height: heightObject.getValueBased(onSize: size)) caretView.frame = CGRect(x: 0, y: 0, width: widthObject.getValueBased(onSize: size), height: heightObject.getValueBased(onSize: size))
} }
@ -67,23 +67,46 @@ import UIKit
} }
// MARK: - MVMCoreUIMoleculeViewProtocol // MARK: - MVMCoreUIMoleculeViewProtocol
public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) { public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
guard let json = json else { self.json = json;
guard let json = json, let moleculeJSON = json.optionalDictionaryForKey(KeyMolecule) else {
return return
} }
if molecule == nil { if molecule == nil {
if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: json, delegateObject: delegateObject) { if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: true) {
contentView.addSubview(moleculeView) contentView.addSubview(moleculeView)
NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: moleculeView.needsToBeConstrained?() ?? false).values)) NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: moleculeView.needsToBeConstrained?() ?? false).values))
molecule = moleculeView molecule = moleculeView
} }
} else { } else {
molecule?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) molecule?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData)
} }
backgroundColor = molecule?.backgroundColor backgroundColor = molecule?.backgroundColor
// Add the caret if there is an action and it's not declared hidden.
if let _ = json.optionalDictionaryForKey("actionMap"), !json.boolForKey("hideArrow") {
addCaretViewAccessory()
} else {
accessoryView = nil
}
// override the separator
if let separator = json.optionalDictionaryForKey("separator") {
addSeparatorsIfNeeded()
bottomSeparatorView?.setWithJSON(separator, delegateObject: delegateObject, additionalData: additionalData)
}
} }
// MARK: - Convenience public static func estimatedHeight(forRow json: [AnyHashable : Any]?) -> CGFloat {
guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule),
let theClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON, delegateObject: nil),
let estimatedHeightFor = theClass.estimatedHeight else {
return 0
}
return estimatedHeightFor(moleculeJSON)
}
// MARK: - Arrow
/// Adds the standard mvm style caret to the accessory view /// Adds the standard mvm style caret to the accessory view
public func addCaretViewAccessory() { public func addCaretViewAccessory() {
guard accessoryView == nil else { guard accessoryView == nil else {
@ -98,6 +121,34 @@ import UIKit
accessoryView = caretView accessoryView = caretView
} }
// MARK: - MoleculeListCellProtocol
public static func moleculeName(_ molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? {
return molecule?.optionalDictionaryForKey(KeyMolecule)?.optionalStringForKey(KeyMoleculeName)
}
/// For when the separator between cells shows using json and frequency. Default is type: standard, frequency: allExceptTop.
public func setSeparatorWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?, indexPath: IndexPath) {
addSeparatorsIfNeeded()
if let json = json {
topSeparatorView?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
bottomSeparatorView?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
if let separatorFrequencyString = json.optionalStringForKey("frequency"), let separatorFrequency = SeparatorFrequency(rawValue: separatorFrequencyString) {
setSeparatorFrequency(separatorFrequency, indexPath: indexPath)
}
} else {
topSeparatorView?.hide()
bottomSeparatorView?.setAsLight()
setSeparatorFrequency(MoleculeTableViewCell.SeparatorFrequency.AllExceptTop, indexPath: indexPath)
}
}
public func didSelectCell(atIndex indexPath: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
if let actionMap = json?.optionalDictionaryForKey("actionMap") {
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
}
}
// MARK: - Separator
func addSeparatorsIfNeeded() { func addSeparatorsIfNeeded() {
if topSeparatorView == nil { if topSeparatorView == nil {
topSeparatorView = SeparatorView.separatorAdd(to: self, position: SeparatorPositionTop) topSeparatorView = SeparatorView.separatorAdd(to: self, position: SeparatorPositionTop)
@ -109,19 +160,6 @@ import UIKit
} }
} }
/// For when the separator between cells shows using json and frequency.
public func setSeparatorWithJSON(_ json: [AnyHashable : Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?, indexPath: IndexPath) {
guard let json = json else {
return
}
addSeparatorsIfNeeded()
topSeparatorView?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
bottomSeparatorView?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
if let separatorFrequencyString = json.optionalStringForKey("frequency"), let separatorFrequency = SeparatorFrequency(rawValue: separatorFrequencyString) {
setSeparatorFrequency(separatorFrequency, indexPath: indexPath)
}
}
/// For when the separator between cells shows. /// For when the separator between cells shows.
public func setSeparatorFrequency(_ separatorFrequency: SeparatorFrequency, indexPath: IndexPath) { public func setSeparatorFrequency(_ separatorFrequency: SeparatorFrequency, indexPath: IndexPath) {
switch separatorFrequency { switch separatorFrequency {

View File

@ -8,7 +8,7 @@
import Foundation import Foundation
public class ProgressBar: UIProgressView, MVMCoreUIMoleculeViewProtocol { public class ProgressBar: UIProgressView {
var isRounded = Bool() var isRounded = Bool()
var thickness : Float = 0.0 { var thickness : Float = 0.0 {
@ -24,7 +24,7 @@ public class ProgressBar: UIProgressView, MVMCoreUIMoleculeViewProtocol {
} }
} }
open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
isRounded = json?.optionalBoolForKey("roundedRect") ?? false isRounded = json?.optionalBoolForKey("roundedRect") ?? false
thickness = json?.floatFromStringForKey("thickness") ?? Float(0.0) thickness = json?.floatFromStringForKey("thickness") ?? Float(0.0)
let percentage = json?.floatFromStringForKey("percent") let percentage = json?.floatFromStringForKey("percent")

View File

@ -20,7 +20,7 @@ import UIKit
return true return true
} }
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
progress.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) progress.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)

View File

@ -93,7 +93,7 @@ public class StandardFooterView: ViewConstrainingView {
layoutIfNeeded() layoutIfNeeded()
} }
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
if let colorString = json?.optionalStringForKey(KeyBackgroundColor) { if let colorString = json?.optionalStringForKey(KeyBackgroundColor) {
backgroundColor = .mfGet(forHex: colorString) backgroundColor = .mfGet(forHex: colorString)

View File

@ -110,7 +110,7 @@ public class StandardHeaderView: ViewConstrainingView {
separatorView?.rightPin?.constant = constant separatorView?.rightPin?.constant = constant
} }
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
if let colorString = json?.optionalStringForKey(KeyBackgroundColor) { if let colorString = json?.optionalStringForKey(KeyBackgroundColor) {
backgroundColor = .mfGet(forHex: colorString) backgroundColor = .mfGet(forHex: colorString)

View File

@ -0,0 +1,87 @@
//
// Switch.swift
// MVMCoreUI
//
// Created by Priya on 5/23/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import UIKit
@objcMembers public class Switch: ViewConstrainingView, FormValidationProtocol{
public var mvmSwitch = MVMCoreUISwitch()
var isRequired = false
var delegateObject: DelegateObject?
@objc func switchChanged() {
let delegate = delegateObject as? MVMCoreUIDelegateObject
if let delegate = delegate {
let formValidator = delegate.formValidationProtocol?.formValidatorModel?()
formValidator?.enableByValidation()
}
}
open override func setupView() {
super.setupView()
mvmSwitch.addTarget(self, action: #selector(Switch.switchChanged), for: .valueChanged)
self.clipsToBounds = true
addSubview(mvmSwitch)
mvmSwitch.translatesAutoresizingMaskIntoConstraints = false
setupContainerConstraints()
}
public override func updateView(_ size: CGFloat) {
super.updateView(size)
mvmSwitch.updateView(size)
}
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
isRequired = json?[KeyRequired] as? Bool ?? false
self.delegateObject = delegateObject
if let delegateObject = delegateObject {
FormValidator.setupValidation(molecule: self, delegate: delegateObject.formValidationProtocol)
}
if let onColorString = json?.optionalStringForKey("onTintColor") {
mvmSwitch.onTintColor = .mfGet(forHex: onColorString)
}
if let offColorString = json?.optionalStringForKey("offTintColor") {
mvmSwitch.offTintColor = .mfGet(forHex: offColorString)
}
if let onKnobColorString = json?.optionalStringForKey("onKnobTintColor") {
mvmSwitch.onKnobTintColor = .mfGet(forHex: onKnobColorString)
}
if let offKnobColorString = json?.optionalStringForKey("offKnobTintColor") {
mvmSwitch.offKnobTintColor = .mfGet(forHex: offKnobColorString)
}
mvmSwitch.setState(json?.optionalBoolForKey("state") ?? false, animated: true)
}
func setupContainerConstraints() {
mvmSwitch.topAnchor.constraint(equalTo: topAnchor).isActive = true
mvmSwitch.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
mvmSwitch.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
mvmSwitch.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
}
public func isValidField() -> Bool {
return (isRequired == false) ? true : mvmSwitch.isOn
}
public func formFieldName() -> String? {
return json?.optionalStringForKey(KeyFieldKey)
}
public func formFieldValue() -> Any? {
return mvmSwitch.isOn
}
public override func needsToBeConstrained() -> Bool {
return true
}
public override func moleculeAlignment() -> UIStackView.Alignment {
return UIStackView.Alignment.leading
}
}

View File

@ -0,0 +1,121 @@
//
// SwitchLineItem.swift
// MVMCoreUI
//
// Created by Priya on 5/6/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import UIKit
@objcMembers public class SwitchLineItem: ViewConstrainingView, FormValidationProtocol{
public var mvmSwitch = Switch()
public var label = Label()
public var leftContainerView = UIView()
public var mfTextButton = MFTextButton(nil, constrainHeight: true, forWidth: 0)
var isRequired = false
var delegateObject: DelegateObject?
@objc func switchChanged() {
let delegate = delegateObject as? MVMCoreUIDelegateObject
if let delegate = delegate {
let formValidator = delegate.formValidationProtocol?.formValidatorModel?()
formValidator?.enableByValidation()
}
}
open override func setupView() {
super.setupView()
leftContainerView.addSubview(label)
leftContainerView.addSubview(mfTextButton)
addSubview(leftContainerView)
addSubview(mvmSwitch)
leftContainerView.translatesAutoresizingMaskIntoConstraints = false
mvmSwitch.translatesAutoresizingMaskIntoConstraints = false
mfTextButton.translatesAutoresizingMaskIntoConstraints = false
label.translatesAutoresizingMaskIntoConstraints = false
setupContainerConstraints()
}
public override func updateView(_ size: CGFloat) {
super.updateView(size)
label.updateView(size)
mvmSwitch.updateView(size)
mfTextButton.updateView(size)
}
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
mvmSwitch.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
label.setWithJSON(json?.optionalDictionaryForKey("label"), delegateObject: delegateObject, additionalData: additionalData)
mfTextButton.setWithJSON(json?.optionalDictionaryForKey("textButton"), delegateObject: delegateObject, additionalData: additionalData)
if (label.text?.count ?? 0) <= 0 && (mfTextButton.titleLabel?.text?.count ?? 0) <= 0 {
mvmSwitch.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0).isActive = true
}
}
func setupContainerConstraints() {
leftContainerView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor).isActive = true
var constraint = leftContainerView.topAnchor.constraint(equalTo: topAnchor)
constraint.priority = UILayoutPriority(249)
constraint.isActive = true
mvmSwitch.topAnchor.constraint(greaterThanOrEqualTo: topAnchor).isActive = true
constraint = mvmSwitch.topAnchor.constraint(equalTo: topAnchor)
constraint.priority = UILayoutPriority(249)
constraint.isActive = true
trailingAnchor.constraint(equalTo: mvmSwitch.trailingAnchor).isActive = true
constraint = bottomAnchor.constraint(equalTo: mvmSwitch.bottomAnchor)
constraint.priority = UILayoutPriority(249)
constraint.isActive = true
bottomAnchor.constraint(greaterThanOrEqualTo: mvmSwitch.bottomAnchor).isActive = true
constraint = bottomAnchor.constraint(equalTo: leftContainerView.bottomAnchor)
constraint.isActive = true
bottomAnchor.constraint(greaterThanOrEqualTo: leftContainerView.bottomAnchor).isActive = true
leftContainerView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
NSLayoutConstraint.constraintPinSubview(leftContainerView, pinCenterX: false, pinCenterY: true)
constraint = mvmSwitch.leadingAnchor.constraint(greaterThanOrEqualTo: leftContainerView.trailingAnchor)
constraint.priority = UILayoutPriority(999)
constraint.isActive = true
NSLayoutConstraint.constraintPinSubview(mvmSwitch, pinCenterX: false, pinCenterY: true)
leftContainerView.topAnchor.constraint(equalTo: label.topAnchor).isActive = true
leftContainerView.trailingAnchor.constraint(greaterThanOrEqualTo: label.trailingAnchor).isActive = true
constraint = leftContainerView.trailingAnchor.constraint(equalTo: label.trailingAnchor)
constraint.priority = UILayoutPriority(249)
constraint.isActive = true
leftContainerView.trailingAnchor.constraint(greaterThanOrEqualTo: mfTextButton.trailingAnchor).isActive = true
constraint = leftContainerView.trailingAnchor.constraint(equalTo: mfTextButton.trailingAnchor)
constraint.priority = UILayoutPriority(249)
constraint.isActive = true
leftContainerView.bottomAnchor.constraint(equalTo: mfTextButton.bottomAnchor).isActive = true
mfTextButton.leadingAnchor.constraint(equalTo: leftContainerView.leadingAnchor).isActive = true
label.leadingAnchor.constraint(equalTo: leftContainerView.leadingAnchor).isActive = true
mfTextButton.topAnchor.constraint(equalTo: label.bottomAnchor).isActive = true
leftContainerView.setContentHuggingPriority(.defaultHigh, for: .horizontal)
mvmSwitch.setContentHuggingPriority(.defaultLow, for: .horizontal)
}
public override func needsToBeConstrained() -> Bool {
return true
}
public override func moleculeAlignment() -> UIStackView.Alignment {
return UIStackView.Alignment.leading
}
}

View File

@ -39,7 +39,7 @@ import UIKit
} }
// MARK: - MVMCoreUIMoleculeViewProtocol // MARK: - MVMCoreUIMoleculeViewProtocol
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) { if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) {
backgroundColor = UIColor.mfGet(forHex: backgroundColorString) backgroundColor = UIColor.mfGet(forHex: backgroundColorString)
@ -142,7 +142,7 @@ import UIKit
} }
} }
open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON, legacy: false) setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON, legacy: false)
setDefaultCustom() setDefaultCustom()
primaryButton?.setWithJSON(primaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData) primaryButton?.setWithJSON(primaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData)

View File

@ -12,11 +12,17 @@ open class MVMCoreUIDelegateObject: DelegateObject {
public weak var formValidationProtocol: FormValidationProtocol? public weak var formValidationProtocol: FormValidationProtocol?
public weak var buttonDelegate: ButtonDelegateProtocol? public weak var buttonDelegate: ButtonDelegateProtocol?
public weak var uiTextFieldDelegate: UITextFieldDelegate? public weak var uiTextFieldDelegate: UITextFieldDelegate?
public weak var moleculeDelegate: MoleculeDelegateProtocol?
open override func setAll(withDelegate delegate: Any) { open override func setAll(withDelegate delegate: Any) {
super.setAll(withDelegate: delegate) super.setAll(withDelegate: delegate)
formValidationProtocol = delegate as? FormValidationProtocol formValidationProtocol = delegate as? FormValidationProtocol
buttonDelegate = delegate as? ButtonDelegateProtocol buttonDelegate = delegate as? ButtonDelegateProtocol
uiTextFieldDelegate = delegate as? UITextFieldDelegate uiTextFieldDelegate = delegate as? UITextFieldDelegate
moleculeDelegate = delegate as? MoleculeDelegateProtocol
}
class func delegateObject(from controller: MVMCoreViewControllerProtocol?) -> MVMCoreUIDelegateObject? {
return controller?.delegateObject?() as? MVMCoreUIDelegateObject
} }
} }

View File

@ -8,21 +8,35 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import <MVMCoreUI/MVMCoreUIMoleculeViewProtocol.h> #import <MVMCoreUI/MVMCoreUIMoleculeViewProtocol.h>
@class DelegateObject; @class MVMCoreUIDelegateObject;
@class MVMCoreLoadObject;
@class MVMCoreErrorObject;
@interface MVMCoreUIMoleculeMappingObject : NSObject @interface MVMCoreUIMoleculeMappingObject : NSObject
// Maps molecule name to class. /// Maps molecule name to class.
@property (nullable, strong, nonatomic) NSMutableDictionary <NSString *, Class> *moleculeMapping; @property (nonnull, strong, nonatomic) NSMutableDictionary <NSString *, Class> *moleculeMapping;
// Returns the shared instance /// Returns the shared instance
+ (nullable instancetype)sharedMappingObject; + (nullable instancetype)sharedMappingObject;
// Returns the molecule for the given name. /// Returns the molecule class.
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForName:(nonnull NSString *)name; - (nullable Class)getMoleculeClassWithJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject;
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject;
// Similar to above but also checks if the molecule needs to be constrained for a stack. #pragma mark - Molecule Creation
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForStackWithJSON:(nonnull NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject;
/// Creates the molecule for the given name.
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForName:(nonnull NSString *)name;
/// Creates the molecule for the molecule json. Takes into account moduleMolecule as well.
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject;
/// Creates the molecule for the molecule json. Takes into account moduleMolecule as well. Also checks if the molecule needs to be constrained for a stack/list style situation.
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject constrainIfNeeded:(BOOL)constrainIfNeeded;
#pragma mark - ModuleMolecule Helpers
/// If the molecule is a module molecule, will get the map for the molecule to load from a module. Otherwise nil.
+ (nullable NSDictionary *)getMoleculeMapForModuleMolecule:(nullable NSDictionary *)moduleMolecule delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject error:(MVMCoreErrorObject *_Nullable *_Nullable)error;
@end @end

View File

@ -9,6 +9,7 @@
#import "MVMCoreUIMoleculeMappingObject.h" #import "MVMCoreUIMoleculeMappingObject.h"
@import MVMCore.MVMCoreActionUtility; @import MVMCore.MVMCoreActionUtility;
@import MVMCore.NSDictionary_MFConvenience; @import MVMCore.NSDictionary_MFConvenience;
@import MVMCore.MVMCoreLoadObject;
#import "MVMCoreUIObject.h" #import "MVMCoreUIObject.h"
#import <MVMCoreUI/MVMCoreUI-Swift.h> #import <MVMCoreUI/MVMCoreUI-Swift.h>
#import "MFTextField.h" #import "MFTextField.h"
@ -35,7 +36,12 @@
@"textField" : MFTextField.class, @"textField" : MFTextField.class,
@"checkbox" : MVMCoreUICheckBox.class, @"checkbox" : MVMCoreUICheckBox.class,
@"progressBarView" : ProgressBarView.class, @"progressBarView" : ProgressBarView.class,
@"progressBar": ProgressBar.class @"progressBar": ProgressBar.class,
@"textField": MFTextField.class,
@"checkbox": MVMCoreUICheckBox.class,
@"listItem": MoleculeTableViewCell.class,
@"switchLineItem": SwitchLineItem.class,
@"switch": Switch.class
} mutableCopy]; } mutableCopy];
}); });
return mapping; return mapping;
@ -46,7 +52,18 @@
return [MVMCoreActionUtility initializerClassCheck:[MVMCoreUIObject sharedInstance].moleculeMap classToVerify:self]; return [MVMCoreActionUtility initializerClassCheck:[MVMCoreUIObject sharedInstance].moleculeMap classToVerify:self];
} }
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForName:(nonnull NSString *)name { - (nullable Class)getMoleculeClassWithJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject {
NSDictionary *moleculeJSON = [MVMCoreUIMoleculeMappingObject getMoleculeMapForModuleMolecule:json delegateObject:delegateObject error:nil] ?: json;
NSString *moleculeName = [moleculeJSON string:KeyMoleculeName];
if (moleculeName) {
return [self.moleculeMapping objectForKey:moleculeName];
}
return nil;
}
#pragma mark - Molecule Creation
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForName:(nonnull NSString *)name {
Class class = [self.moleculeMapping objectForKey:name]; Class class = [self.moleculeMapping objectForKey:name];
if (!class) { if (!class) {
return nil; return nil;
@ -58,28 +75,38 @@
return molecule; return molecule;
} }
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject { - (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject {
NSString *moleculeName = [json string:KeyMoleculeName]; return [self createMoleculeForJSON:json delegateObject:delegateObject constrainIfNeeded:NO];
}
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject constrainIfNeeded:(BOOL)constrainIfNeeded {
NSDictionary *moleculeJSON = [MVMCoreUIMoleculeMappingObject getMoleculeMapForModuleMolecule:json delegateObject:delegateObject error:nil] ?: json;
NSString *moleculeName = [moleculeJSON string:KeyMoleculeName];
if (!moleculeName) { if (!moleculeName) {
return nil; return nil;
} }
UIView <MVMCoreUIMoleculeViewProtocol>*molecule = [self getMoleculeForName:moleculeName]; UIView <MVMCoreUIMoleculeViewProtocol>*molecule = [self createMoleculeForName:moleculeName];
[molecule setWithJSON:json delegateObject:delegateObject additionalData:nil]; if (constrainIfNeeded && [molecule respondsToSelector:@selector(needsToBeConstrained)] && [molecule needsToBeConstrained]) {
molecule = [[ViewConstrainingView alloc] initWithMolecule:molecule alignment:[molecule respondsToSelector:@selector(moleculeAlignment)] ? [molecule moleculeAlignment] : UIStackViewAlignmentFill];
}
[molecule setWithJSON:moleculeJSON delegateObject:delegateObject additionalData:nil];
return molecule; return molecule;
} }
#pragma mark - ModuleMolecule Helpers
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForStackWithJSON:(nonnull NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject { + (nullable NSDictionary *)getMoleculeMapForModuleMolecule:(nullable NSDictionary *)moduleMolecule delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject error:(MVMCoreErrorObject *_Nullable *_Nullable)error {
NSString *moleculeName = [json string:KeyMoleculeName]; NSString *moleculeName = [moduleMolecule string:KeyMoleculeName];
if (!moleculeName) { if ([moleculeName isEqualToString:@"moduleMolecule"]) {
NSString *moduleName = [moduleMolecule string:@"moduleName"];
NSDictionary *module = moduleName ? [delegateObject.moleculeDelegate getModuleWithName:moduleName] : nil;
if (!module && error) {
*error = [[MVMCoreErrorObject alloc] initWithTitle:nil message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeModuleMolecule domain:ErrorDomainNative location:NSStringFromClass(self)];
}
return module;
} else {
return nil; return nil;
} }
UIView <MVMCoreUIMoleculeViewProtocol>*molecule = [self getMoleculeForName:moleculeName];
if ([molecule respondsToSelector:@selector(needsToBeConstrained)] && [molecule needsToBeConstrained]) {
molecule = [[ViewConstrainingView alloc] initWithMolecule:molecule alignment:[molecule respondsToSelector:@selector(moleculeAlignment)] ? [molecule moleculeAlignment] : UIStackViewAlignmentFill];
}
[molecule setWithJSON:json delegateObject:delegateObject additionalData:nil];
return molecule;
} }
@end @end

View File

@ -0,0 +1,15 @@
//
// MoleculeDelegateProtocol.h
// MVMCoreUI
//
// Created by Scott Pfeil on 5/22/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol MoleculeDelegateProtocol <NSObject>
/// returns a module for the corresponding module name.
- (nullable NSDictionary *)getModuleWithName:(nullable NSString *)name;
@end

View File

@ -0,0 +1,47 @@
//
// MoleculeMappingObject+Extension.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 5/23/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import Foundation
public extension MVMCoreUIMoleculeMappingObject {
/// Gets the molecule, and if it belonged to a moduleMolecule, the module name or error.
static func getMoleculeJSON(for map: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> (molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)? {
guard let map = map, let moleculeName = map.optionalStringForKey(KeyMoleculeName) else {
return nil
}
guard moleculeName == "moduleMolecule" else {
// Not a module molecule.
return (map, nil, nil)
}
guard let moduleName = map.optionalStringForKey("moduleName"),
let module = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
guard let error = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess), code: CoreUIErrorCode.ErrorCodeModuleMolecule.rawValue, domain: ErrorDomainNative, location: String(describing: self)) else {
return nil
}
MVMCoreUILoggingHandler.shared()?.addError(toLog: error)
return (nil, nil, error)
}
return (module, moduleName, nil)
}
/// Gets the molecule, and if it belonged to a moduleMolecule adds the module name or error to the passed lists.
static func getMoleculeJSON(for map: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, moduleNames: inout [String]?, errors: inout [MVMCoreErrorObject]?) -> [AnyHashable: Any]? {
guard let molecule = getMoleculeJSON(for: map, delegateObject: delegateObject) else {
return nil
}
if let moduleName = molecule.moduleName {
moduleNames?.append(moduleName)
}
if let error = molecule.error {
errors?.append(error)
}
return molecule.molecule
}
}

View File

@ -157,6 +157,13 @@ B3 -> Legal
//75Bd 10pt only for support //75Bd 10pt only for support
+ (nullable UIFont *)fontForUnreadMessageOnSupport; + (nullable UIFont *)fontForUnreadMessageOnSupport;
//55Rg 16pt for 5G flow
+ (nullable UIFont *)font5GMessage:(BOOL)genericScaling;
//55Rg 16pt for 5G flow scale YES
+ (nullable UIFont *)font5GMessage;
// Returns the fonts for these styles allowing to apply a generic scale by device or not. // Returns the fonts for these styles allowing to apply a generic scale by device or not.
+ (nullable UIFont *)fontForBiggerHeadLine:(BOOL)genericScaling; + (nullable UIFont *)fontForBiggerHeadLine:(BOOL)genericScaling;
+ (nullable UIFont *)fontForPlan:(BOOL)genericScaling; + (nullable UIFont *)fontForPlan:(BOOL)genericScaling;

View File

@ -347,6 +347,19 @@ CGFloat const LabelWithInternalButtonLineSpace = 2;
return [MFFonts mfFont75Bd:size]; return [MFFonts mfFont75Bd:size];
} }
+ (nullable UIFont *)font5GMessage:(BOOL)genericScaling {
CGFloat size = 16;
if (genericScaling) {
size = [self sizeFontGenericForCurrentDevice:size];
}
return [MFFonts mfFont55Rg:size];
}
+ (nullable UIFont *)font5GMessage {
return [self font5GMessage:YES];
}
+ (nullable UIFont *)fontForHeadlineAlternative:(BOOL)genericScaling { + (nullable UIFont *)fontForHeadlineAlternative:(BOOL)genericScaling {
CGFloat size = 24; CGFloat size = 24;
if (genericScaling) { if (genericScaling) {

View File

@ -0,0 +1,22 @@
//
// MoleculeListCellProtocol.h
// MVMCoreUI
//
// Created by Scott Pfeil on 5/22/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
#import <UIKit/UIKit.h>
@class MVMCoreUIDelegateObject;
@protocol MoleculeListCellProtocol <NSObject>
@optional
/// Can override the molecule name for the given molecule. Otherwise we assume value for key moleculeName.
+ (nullable NSString *)moleculeName:(nullable NSDictionary *)molecule delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject;
/// Can set the separator according to what the moleculeList commands.
- (void)setSeparatorWithJSON:(nullable NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData indexPath:(nonnull NSIndexPath *)indexPath;
/// Handle action
- (void)didSelectCellAtIndex:(nonnull NSIndexPath *)indexPath delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData;
@end

View File

@ -9,28 +9,33 @@
import UIKit import UIKit
open class MoleculeListTemplate: ThreeLayerTableViewController { open class MoleculeListTemplate: ThreeLayerTableViewController {
var molecules: [(molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)]?
open override func registerWithTable() { open override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
super.registerWithTable() var shouldFinish = super.shouldFinishProcessingLoad(loadObject, error: error)
guard let molecules = loadObject?.pageJSON?.arrayForKey(KeyMolecules) else { guard shouldFinish else {
return return shouldFinish
} }
for case let molecule as Dictionary<AnyHashable, Any> in molecules {
if let moleculeName = molecule.optionalStringForKey(KeyMoleculeName) { if let firstError = setup()?.first {
tableView?.register(MoleculeTableViewCell.self, forCellReuseIdentifier: moleculeName) // Don't continue if there was an error loading needed modules.
} error.pointee = firstError
shouldFinish = false
} }
return shouldFinish
} }
open override func viewForTop() -> UIView { open override func viewForTop() -> UIView {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) else { guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"),
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else {
return super.viewForTop() return super.viewForTop()
} }
return molecule return molecule
} }
override open func viewForBottom() -> UIView { override open func viewForBottom() -> UIView {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) else { guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"),
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else {
return viewForBottom() return viewForBottom()
} }
return molecule return molecule
@ -38,31 +43,142 @@ open class MoleculeListTemplate: ThreeLayerTableViewController {
open override func newDataBuildScreen() { open override func newDataBuildScreen() {
super.newDataBuildScreen() super.newDataBuildScreen()
_ = setupMoleculeList()
registerWithTable() registerWithTable()
} }
open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { // MARK: - table
if let moleculeName = loadObject?.pageJSON?.stringOptionalWithChainOfKeysOrIndexes([KeyMolecules,indexPath.row,KeyMoleculeName]), let theClass = MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping?[moleculeName] as? MVMCoreUIMoleculeViewProtocol.Type, open override func registerWithTable() {
let estimatedHeightForRow = theClass.estimatedHeightForRow { super.registerWithTable()
return estimatedHeightForRow() guard let molecules = molecules else {
return
} }
return 0 for molecule in molecules {
if let moleculeInfo = getMoleculeInfo(with: molecule), let moleculeToRegister = moleculeInfo.name {
tableView?.register(moleculeInfo.class, forCellReuseIdentifier: moleculeToRegister)
}
}
}
open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
guard let molecule = molecules?[indexPath.row],
let moleculeInfo = getMoleculeInfo(with: molecule),
let estimatedHeight = moleculeInfo.class.estimatedHeight else {
return 0
}
return estimatedHeight(molecule.molecule)
} }
open override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { open override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return loadObject?.pageJSON?.arrayForKey(KeyMolecules).count ?? 0 return molecules?.count ?? 0
} }
open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let molecule = loadObject?.pageJSON?.optionalDictionaryWithChainOfKeysOrIndexes([KeyMolecules,indexPath.row]), guard let molecule = molecules?[indexPath.row],
let moleculeName = molecule.optionalStringForKey(KeyMoleculeName), let moleculeInfo = getMoleculeInfo(with: molecule),
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeName) as? MoleculeTableViewCell else { let moleculeName = moleculeInfo.name,
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeName) else {
return UITableViewCell() return UITableViewCell()
} }
let delegate = delegateObject() let delegate = delegateObject() as? MVMCoreUIDelegateObject
cell.setWithJSON(molecule, delegateObject: delegate, additionalData: nil) if let protocolCell = cell as? MoleculeListCellProtocol {
cell.setSeparatorWithJSON(loadObject?.pageJSON?.optionalDictionaryForKey("separator"), delegateObject: delegate, additionalData: nil, indexPath: indexPath) protocolCell.setSeparatorWithJSON?(loadObject?.pageJSON?.optionalDictionaryForKey("separator"), delegateObject: delegate, additionalData: nil, indexPath: indexPath)
cell.updateView(tableView.bounds.width) }
if let protocolCell = cell as? MVMCoreUIMoleculeViewProtocol {
protocolCell.setWithJSON(molecule.molecule, delegateObject: delegate, additionalData: nil)
protocolCell.updateView(tableView.bounds.width)
}
return cell return cell
} }
open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? MoleculeListCellProtocol {
cell.didSelectCell?(atIndex: indexPath, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
}
}
// MARK: - cache handling
open override func pageTypesToListenFor() -> [Any]? {
guard let pageType = self.pageType else {
return super.pageTypesToListenFor()
}
return [pageType]
}
open override func modulesToListenFor() -> [Any]? {
// Get all of the molecules that need modules.
return modulesNeeded()
}
// MARK: - Module Molecule Handling
/// Returns the (name, class) of the molecule for the given map.
func getMoleculeInfo(with molecule: (molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)) -> (name: String?, class: AnyClass)? {
guard let map = molecule.molecule, let moleculeName = map.optionalStringForKey(KeyMoleculeName), let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping[moleculeName] as? AnyClass else {
return nil
}
if let moleculeClass = moleculeClass as? MoleculeListCellProtocol.Type, let moleculeNameFunc = moleculeClass.moleculeName {
return (moleculeNameFunc(map, delegateObject() as? MVMCoreUIDelegateObject), moleculeClass)
} else {
return (moleculeName, moleculeClass)
}
}
/// Sets up the molecule list and ensures no errors loading all content.
func setupMoleculeList() -> [MVMCoreErrorObject]? {
var errors: [MVMCoreErrorObject] = []
let delegate = delegateObject() as? MVMCoreUIDelegateObject
var moleculeList: [(molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)] = []
if let molecules = loadObject?.pageJSON?.optionalArrayForKey(KeyMolecules) as? [[AnyHashable: Any]] {
for molecule in molecules {
if let object = MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: molecule, delegateObject: delegate) {
if let error = object.error {
errors.append(error)
} else {
moleculeList.append(object)
}
}
}
}
molecules = moleculeList
return errors.count > 0 ? errors : nil
}
/// Sets up the header, footer, molecule list and ensures no errors loading all content.
func setup() -> [MVMCoreErrorObject]? {
var errors: [MVMCoreErrorObject] = []
let delegate = delegateObject() as? MVMCoreUIDelegateObject
MoleculeListTemplate.addToErrorList(with: MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate), errors: &errors)
MoleculeListTemplate.addToErrorList(with: MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate), errors: &errors)
if let newErrors = setupMoleculeList() {
errors.append(contentsOf: newErrors)
}
return errors.count > 0 ? errors : nil
}
static func addToErrorList(with moleculeObject: (molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)?, errors: inout [MVMCoreErrorObject]) {
if let error = moleculeObject?.error {
errors.append(error)
}
}
static func addToModuleList(with moleculeObject: (molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)?, moduleNames: inout [String]) {
if let moduleName = moleculeObject?.moduleName {
moduleNames.append(moduleName)
}
}
/// Gets a list of required modules
func modulesNeeded() -> [String]? {
var modules: [String] = []
let delegate = delegateObject() as? MVMCoreUIDelegateObject
MoleculeListTemplate.addToModuleList(with: MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate), moduleNames: &modules)
MoleculeListTemplate.addToModuleList(with: MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate), moduleNames: &modules)
if let molecules = molecules {
for molecule in molecules {
MoleculeListTemplate.addToModuleList(with: molecule, moduleNames: &modules)
}
}
return (modules.count > 0 ? modules : nil)
}
} }

View File

@ -8,27 +8,8 @@
import UIKit import UIKit
public class MoleculeStackCenteredTemplate: ThreeLayerViewController { public class MoleculeStackCenteredTemplate: MoleculeStackTemplate {
public override func spaceBetweenTopAndMiddle() -> CGFloat? {
public override func viewForMiddle() -> UIView? { return nil
let molecule = loadObject?.pageJSON?.optionalDictionaryForKey("moleculeStack")
let moleculeStack = MoleculeStackView(withJSON: molecule, delegateObject: delegateObject(), additionalData: nil)
return moleculeStack
}
public override func viewForTop() -> UIView? {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"),
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) else {
return nil
}
return molecule
}
override public func viewForBottom() -> UIView? {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"),
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) else {
return nil
}
return molecule
} }
} }

View File

@ -10,13 +10,22 @@ import UIKit
public class MoleculeStackTemplate: ThreeLayerViewController { public class MoleculeStackTemplate: ThreeLayerViewController {
public override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
var shouldFinish = super.shouldFinishProcessingLoad(loadObject, error: error)
if shouldFinish, let firstError = modulesNeeded().errors?.first {
// Don't continue if there was an error loading needed modules.
error.pointee = firstError
shouldFinish = false
}
return shouldFinish
}
public override func spaceBetweenTopAndMiddle() -> CGFloat? { public override func spaceBetweenTopAndMiddle() -> CGFloat? {
return 0 return 0
} }
public override func viewForTop() -> UIView? { public override func viewForTop() -> UIView? {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) else { guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else {
return nil return nil
} }
return molecule return molecule
@ -26,13 +35,42 @@ public class MoleculeStackTemplate: ThreeLayerViewController {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("moleculeStack") else { guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("moleculeStack") else {
return nil return nil
} }
return MoleculeStackView(withJSON: moleculeJSON, delegateObject: delegateObject(), additionalData: nil) return MoleculeStackView(withJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
} }
override public func viewForBottom() -> UIView? { override public func viewForBottom() -> UIView? {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) else { guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else {
return nil return nil
} }
return molecule return molecule
} }
// MARK: - cache handling
public override func pageTypesToListenFor() -> [Any]? {
guard let pageType = self.pageType else {
return super.pageTypesToListenFor()
}
return [pageType]
}
public override func modulesToListenFor() -> [Any]? {
// Get all of the molecules that need modules.
return modulesNeeded().modules
}
// MARK: - Module Molecule Handling
func modulesNeeded() -> (modules: [String]?, errors: [MVMCoreErrorObject]?) {
var modules: [String]? = []
var errors: [MVMCoreErrorObject]? = []
let delegate = delegateObject() as? MVMCoreUIDelegateObject
let _ = MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate, moduleNames: &modules, errors: &errors)
let _ = MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate, moduleNames: &modules, errors: &errors)
if let molecules = loadObject?.pageJSON?.optionalArrayForChainOfKeysOrIndexes(["moleculeStack",KeyMolecules]) as? [[AnyHashable: Any]] {
for molecule in molecules {
let _ = MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: molecule, delegateObject: delegate, moduleNames: &modules, errors: &errors)
}
}
return (modules?.count ?? 0 > 0 ? modules : nil, errors?.count ?? 0 > 0 ? errors : nil)
}
} }

View File

@ -15,6 +15,7 @@ extern NSString * const KeyScreenHeading;
extern NSString * const KeyMolecules; extern NSString * const KeyMolecules;
extern NSString * const KeyMoleculeName; extern NSString * const KeyMoleculeName;
extern NSString * const KeyMolecule;
extern NSString * const KeyDisableButton; extern NSString * const KeyDisableButton;
@ -68,3 +69,11 @@ extern BOOL DisableAnimations;
// Hand Scroll Key // Hand Scroll Key
extern NSString * const KeyHandScrollAnimation; extern NSString * const KeyHandScrollAnimation;
extern NSString * const KeyHandScroll; extern NSString * const KeyHandScroll;
#pragma mark - Error Codes
// Native Error Codes (Add new ones to bottom, don't change order!)
typedef NS_ENUM(NSInteger, CoreUIErrorCode) {
ErrorCodeModuleMolecule = 100,
ErrorCodeListMolecule = 101
};

View File

@ -14,6 +14,7 @@ NSString * const KeyScreenHeading = @"screenHeading";
NSString * const KeyMolecules = @"molecules"; NSString * const KeyMolecules = @"molecules";
NSString * const KeyMoleculeName = @"moleculeName"; NSString * const KeyMoleculeName = @"moleculeName";
NSString * const KeyMolecule = @"molecule";
NSString * const KeyDisableButton = @"disableAction"; NSString * const KeyDisableButton = @"disableAction";