merging from develop
This commit is contained in:
commit
664b4fd230
@ -54,7 +54,7 @@
|
|||||||
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, ); }; };
|
||||||
01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */; };
|
01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */; };
|
||||||
01EB368F23609801006832FA /* LabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368823609801006832FA /* LabelModel.swift */; };
|
01EB368F23609801006832FA /* LabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368823609801006832FA /* LabelModel.swift */; };
|
||||||
01EB369023609801006832FA /* ListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368923609801006832FA /* ListItemModel.swift */; };
|
01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368923609801006832FA /* MoleculeListItemModel.swift */; };
|
||||||
01EB369223609801006832FA /* MoleculeStackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368B23609801006832FA /* MoleculeStackModel.swift */; };
|
01EB369223609801006832FA /* MoleculeStackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368B23609801006832FA /* MoleculeStackModel.swift */; };
|
||||||
01EB369323609801006832FA /* HeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368C23609801006832FA /* HeaderModel.swift */; };
|
01EB369323609801006832FA /* HeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368C23609801006832FA /* HeaderModel.swift */; };
|
||||||
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368D23609801006832FA /* HeadlineBodyModel.swift */; };
|
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368D23609801006832FA /* HeadlineBodyModel.swift */; };
|
||||||
@ -102,6 +102,10 @@
|
|||||||
0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; };
|
0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; };
|
||||||
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; };
|
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; };
|
||||||
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; };
|
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; };
|
||||||
|
5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5248BFEA23F12E350059236A /* ListThreeColumnPlanDataDivider.swift */; };
|
||||||
|
5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */; };
|
||||||
|
8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */; };
|
||||||
|
8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */; };
|
||||||
9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; };
|
9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; };
|
||||||
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; };
|
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; };
|
||||||
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; };
|
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; };
|
||||||
@ -172,6 +176,7 @@
|
|||||||
D260D7B622D68514007E7233 /* MVMCoreUIPagingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
D260D7B622D68514007E7233 /* MVMCoreUIPagingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368A23609801006832FA /* MoleculeStackItemModel.swift */; };
|
D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368A23609801006832FA /* MoleculeStackItemModel.swift */; };
|
||||||
D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */; };
|
D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */; };
|
||||||
|
D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */; };
|
||||||
D274CA332236A78900B01B62 /* FooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D274CA322236A78900B01B62 /* FooterView.swift */; };
|
D274CA332236A78900B01B62 /* FooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D274CA322236A78900B01B62 /* FooterView.swift */; };
|
||||||
D2755D7B23689C7500485468 /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2755D7A23689C7500485468 /* TableViewCell.swift */; };
|
D2755D7B23689C7500485468 /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2755D7A23689C7500485468 /* TableViewCell.swift */; };
|
||||||
D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */; };
|
D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */; };
|
||||||
@ -314,6 +319,7 @@
|
|||||||
D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2B1E3E422F37D6A0065F95C /* ImageHeadlineBody.swift */; };
|
D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2B1E3E422F37D6A0065F95C /* ImageHeadlineBody.swift */; };
|
||||||
D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */; };
|
D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */; };
|
||||||
|
D2C521A923EDE79E00CA2634 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2C521A823EDE79E00CA2634 /* ViewController.swift */; };
|
||||||
D2D6CD4022E78C1A00D701B8 /* Scroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */; };
|
D2D6CD4022E78C1A00D701B8 /* Scroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */; };
|
||||||
D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */; };
|
D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */; };
|
||||||
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */; };
|
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */; };
|
||||||
@ -386,7 +392,7 @@
|
|||||||
01C851D223CF9E740021F976 /* LabelToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelToggleModel.swift; sourceTree = "<group>"; };
|
01C851D223CF9E740021F976 /* LabelToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelToggleModel.swift; sourceTree = "<group>"; };
|
||||||
01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeModelProtocol.swift; sourceTree = "<group>"; };
|
01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
01EB368823609801006832FA /* LabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelModel.swift; sourceTree = "<group>"; };
|
01EB368823609801006832FA /* LabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelModel.swift; sourceTree = "<group>"; };
|
||||||
01EB368923609801006832FA /* ListItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListItemModel.swift; sourceTree = "<group>"; };
|
01EB368923609801006832FA /* MoleculeListItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeListItemModel.swift; sourceTree = "<group>"; };
|
||||||
01EB368A23609801006832FA /* MoleculeStackItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackItemModel.swift; sourceTree = "<group>"; };
|
01EB368A23609801006832FA /* MoleculeStackItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackItemModel.swift; sourceTree = "<group>"; };
|
||||||
01EB368B23609801006832FA /* MoleculeStackModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackModel.swift; sourceTree = "<group>"; };
|
01EB368B23609801006832FA /* MoleculeStackModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackModel.swift; sourceTree = "<group>"; };
|
||||||
01EB368C23609801006832FA /* HeaderModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderModel.swift; sourceTree = "<group>"; };
|
01EB368C23609801006832FA /* HeaderModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderModel.swift; sourceTree = "<group>"; };
|
||||||
@ -426,6 +432,10 @@
|
|||||||
0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
|
0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
|
||||||
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = "<group>"; };
|
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = "<group>"; };
|
||||||
31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = "<group>"; };
|
31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = "<group>"; };
|
||||||
|
5248BFEA23F12E350059236A /* ListThreeColumnPlanDataDivider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnPlanDataDivider.swift; sourceTree = "<group>"; };
|
||||||
|
5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnPlanDataDividerModel.swift; sourceTree = "<group>"; };
|
||||||
|
8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaret.swift; sourceTree = "<group>"; };
|
||||||
|
8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretModel.swift; sourceTree = "<group>"; };
|
||||||
9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = "<group>"; };
|
9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = "<group>"; };
|
||||||
9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = "<group>"; };
|
9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = "<group>"; };
|
||||||
943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = "<group>"; };
|
943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = "<group>"; };
|
||||||
@ -494,6 +504,7 @@
|
|||||||
D260D7B022D65BDD007E7233 /* MVMCoreUIPageControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIPageControl.m; sourceTree = "<group>"; };
|
D260D7B022D65BDD007E7233 /* MVMCoreUIPageControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIPageControl.m; sourceTree = "<group>"; };
|
||||||
D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIPagingProtocol.h; sourceTree = "<group>"; };
|
D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIPagingProtocol.h; sourceTree = "<group>"; };
|
||||||
D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropDownFilterTableViewCell.swift; sourceTree = "<group>"; };
|
D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropDownFilterTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
|
D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemModel.swift; sourceTree = "<group>"; };
|
||||||
D274CA322236A78900B01B62 /* FooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FooterView.swift; sourceTree = "<group>"; };
|
D274CA322236A78900B01B62 /* FooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FooterView.swift; sourceTree = "<group>"; };
|
||||||
D2755D7A23689C7500485468 /* TableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewCell.swift; sourceTree = "<group>"; };
|
D2755D7A23689C7500485468 /* TableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewCell.swift; sourceTree = "<group>"; };
|
||||||
D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsTableViewCell.swift; sourceTree = "<group>"; };
|
D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
@ -651,6 +662,7 @@
|
|||||||
D2B1E3E422F37D6A0065F95C /* ImageHeadlineBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageHeadlineBody.swift; sourceTree = "<group>"; };
|
D2B1E3E422F37D6A0065F95C /* ImageHeadlineBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageHeadlineBody.swift; sourceTree = "<group>"; };
|
||||||
D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewControllerMappingObject.h; sourceTree = "<group>"; };
|
D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewControllerMappingObject.h; sourceTree = "<group>"; };
|
||||||
D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIViewControllerMappingObject.m; sourceTree = "<group>"; };
|
D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIViewControllerMappingObject.m; sourceTree = "<group>"; };
|
||||||
|
D2C521A823EDE79E00CA2634 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||||
D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scroller.swift; sourceTree = "<group>"; };
|
D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scroller.swift; sourceTree = "<group>"; };
|
||||||
D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerTemplate.swift; sourceTree = "<group>"; };
|
D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerTemplate.swift; sourceTree = "<group>"; };
|
||||||
D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUIDelegateObject.swift; sourceTree = "<group>"; };
|
D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUIDelegateObject.swift; sourceTree = "<group>"; };
|
||||||
@ -665,7 +677,6 @@
|
|||||||
D2E2A99E23E07F8A000B42E6 /* PillButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillButton.swift; sourceTree = "<group>"; };
|
D2E2A99E23E07F8A000B42E6 /* PillButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillButton.swift; sourceTree = "<group>"; };
|
||||||
D2E2A9A023E095AB000B42E6 /* ButtonModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonModelProtocol.swift; sourceTree = "<group>"; };
|
D2E2A9A023E095AB000B42E6 /* ButtonModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableableModelProtocol.swift; sourceTree = "<group>"; };
|
D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableableModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
D2F4DDE52371A4CB00CD28BB /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
|
||||||
D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeContainer.swift; sourceTree = "<group>"; };
|
D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeContainer.swift; sourceTree = "<group>"; };
|
||||||
D2FB151C23A40F1500C20E10 /* MoleculeStackItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackItem.swift; sourceTree = "<group>"; };
|
D2FB151C23A40F1500C20E10 /* MoleculeStackItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackItem.swift; sourceTree = "<group>"; };
|
||||||
DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeftRightLabelView.swift; sourceTree = "<group>"; };
|
DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeftRightLabelView.swift; sourceTree = "<group>"; };
|
||||||
@ -951,8 +962,8 @@
|
|||||||
D22479912316A9EF003FCCF9 /* Items */ = {
|
D22479912316A9EF003FCCF9 /* Items */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D2755D7A23689C7500485468 /* TableViewCell.swift */,
|
D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */,
|
||||||
01EB368923609801006832FA /* ListItemModel.swift */,
|
01EB368923609801006832FA /* MoleculeListItemModel.swift */,
|
||||||
01509D8E2327EC6F00EF99AA /* MoleculeTableViewCell.swift */,
|
01509D8E2327EC6F00EF99AA /* MoleculeTableViewCell.swift */,
|
||||||
012A88C1238D7BCA00FE3DA1 /* CarouselItemModel.swift */,
|
012A88C1238D7BCA00FE3DA1 /* CarouselItemModel.swift */,
|
||||||
D2A6390422CBCE160052ED1F /* MoleculeCollectionViewCell.swift */,
|
D2A6390422CBCE160052ED1F /* MoleculeCollectionViewCell.swift */,
|
||||||
@ -971,6 +982,49 @@
|
|||||||
path = Items;
|
path = Items;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
D22B38E923F4E07800490EF6 /* DesignedComponents */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D22B38EC23F4E10700490EF6 /* SectionDividers */,
|
||||||
|
D22B38EA23F4E08B00490EF6 /* List */,
|
||||||
|
);
|
||||||
|
path = DesignedComponents;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
D22B38EA23F4E08B00490EF6 /* List */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D22B38EB23F4E0AE00490EF6 /* LeftVariable */,
|
||||||
|
);
|
||||||
|
path = List;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
D22B38EB23F4E0AE00490EF6 /* LeftVariable */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */,
|
||||||
|
8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */,
|
||||||
|
);
|
||||||
|
path = LeftVariable;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
D22B38EC23F4E10700490EF6 /* SectionDividers */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D22B38ED23F4E11100490EF6 /* ThreeColumn */,
|
||||||
|
);
|
||||||
|
path = SectionDividers;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
D22B38ED23F4E11100490EF6 /* ThreeColumn */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */,
|
||||||
|
5248BFEA23F12E350059236A /* ListThreeColumnPlanDataDivider.swift */,
|
||||||
|
);
|
||||||
|
path = ThreeColumn;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
D22D1F582204D2590077CEC0 /* Legacy */ = {
|
D22D1F582204D2590077CEC0 /* Legacy */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -1073,6 +1127,7 @@
|
|||||||
D29DF10E21E67A77003B2FB9 /* Molecules */ = {
|
D29DF10E21E67A77003B2FB9 /* Molecules */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
D22B38E923F4E07800490EF6 /* DesignedComponents */,
|
||||||
D22479912316A9EF003FCCF9 /* Items */,
|
D22479912316A9EF003FCCF9 /* Items */,
|
||||||
D224798F2316A99F003FCCF9 /* LeftRightViews */,
|
D224798F2316A99F003FCCF9 /* LeftRightViews */,
|
||||||
D224798E2316A995003FCCF9 /* HorizontalCombinationViews */,
|
D224798E2316A995003FCCF9 /* HorizontalCombinationViews */,
|
||||||
@ -1112,7 +1167,7 @@
|
|||||||
D29DF2CD21E7C104003B2FB9 /* MFLoadingViewController.m */,
|
D29DF2CD21E7C104003B2FB9 /* MFLoadingViewController.m */,
|
||||||
D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */,
|
D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */,
|
||||||
D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */,
|
D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */,
|
||||||
D2F4DDE52371A4CB00CD28BB /* ViewController.swift */,
|
D2C521A823EDE79E00CA2634 /* ViewController.swift */,
|
||||||
);
|
);
|
||||||
path = BaseControllers;
|
path = BaseControllers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1413,6 +1468,7 @@
|
|||||||
D2B18B7E2360913400A9AEDC /* Control.swift */,
|
D2B18B7E2360913400A9AEDC /* Control.swift */,
|
||||||
D2B18B802360945C00A9AEDC /* View.swift */,
|
D2B18B802360945C00A9AEDC /* View.swift */,
|
||||||
0AE14F63238315D2005417F8 /* TextField.swift */,
|
0AE14F63238315D2005417F8 /* TextField.swift */,
|
||||||
|
D2755D7A23689C7500485468 /* TableViewCell.swift */,
|
||||||
0A5D59C323AD488600EFD9E9 /* Protocols */,
|
0A5D59C323AD488600EFD9E9 /* Protocols */,
|
||||||
0A14F6A423E4803A00EDF7F7 /* StackView.swift */,
|
0A14F6A423E4803A00EDF7F7 /* StackView.swift */,
|
||||||
);
|
);
|
||||||
@ -1578,6 +1634,7 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */,
|
||||||
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
|
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
|
||||||
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */,
|
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */,
|
||||||
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */,
|
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */,
|
||||||
@ -1665,7 +1722,7 @@
|
|||||||
012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */,
|
012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */,
|
||||||
D2A514672213885800345BFB /* HeaderView.swift in Sources */,
|
D2A514672213885800345BFB /* HeaderView.swift in Sources */,
|
||||||
D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */,
|
D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */,
|
||||||
01EB369023609801006832FA /* ListItemModel.swift in Sources */,
|
01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */,
|
||||||
D28A838323CCBD3F00DFE4FC /* CircleProgressModel.swift in Sources */,
|
D28A838323CCBD3F00DFE4FC /* CircleProgressModel.swift in Sources */,
|
||||||
D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */,
|
D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */,
|
||||||
DBEFFA04225A829700230692 /* Label.swift in Sources */,
|
DBEFFA04225A829700230692 /* Label.swift in Sources */,
|
||||||
@ -1675,6 +1732,7 @@
|
|||||||
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */,
|
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */,
|
||||||
D260105523CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift in Sources */,
|
D260105523CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift in Sources */,
|
||||||
D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */,
|
D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */,
|
||||||
|
5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */,
|
||||||
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */,
|
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */,
|
||||||
0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */,
|
0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */,
|
||||||
94F217B723E0BF6100A47C06 /* PrimaryButtonView.m in Sources */,
|
94F217B723E0BF6100A47C06 /* PrimaryButtonView.m in Sources */,
|
||||||
@ -1728,6 +1786,7 @@
|
|||||||
94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */,
|
94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */,
|
||||||
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
|
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
|
||||||
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */,
|
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */,
|
||||||
|
8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */,
|
||||||
D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */,
|
D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */,
|
||||||
012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */,
|
012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */,
|
||||||
D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */,
|
D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */,
|
||||||
@ -1741,6 +1800,7 @@
|
|||||||
D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */,
|
D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */,
|
||||||
D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */,
|
D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */,
|
||||||
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */,
|
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */,
|
||||||
|
8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */,
|
||||||
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
|
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
|
||||||
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */,
|
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */,
|
||||||
0A21DB89235E06EF00C160A2 /* MFMdnTextField.m in Sources */,
|
0A21DB89235E06EF00C160A2 /* MFMdnTextField.m in Sources */,
|
||||||
@ -1760,6 +1820,7 @@
|
|||||||
D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */,
|
D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */,
|
||||||
0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */,
|
0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */,
|
||||||
D243859923A16B1800332775 /* Container.swift in Sources */,
|
D243859923A16B1800332775 /* Container.swift in Sources */,
|
||||||
|
D2C521A923EDE79E00CA2634 /* ViewController.swift in Sources */,
|
||||||
D260105B23D0BB7100764D80 /* StackModelProtocol.swift in Sources */,
|
D260105B23D0BB7100764D80 /* StackModelProtocol.swift in Sources */,
|
||||||
D29DF29821E7ADB8003B2FB9 /* MFScrollingViewController.m in Sources */,
|
D29DF29821E7ADB8003B2FB9 /* MFScrollingViewController.m in Sources */,
|
||||||
D28A839323CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift in Sources */,
|
D28A839323CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift in Sources */,
|
||||||
@ -1775,6 +1836,7 @@
|
|||||||
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */,
|
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */,
|
||||||
D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */,
|
D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */,
|
||||||
0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */,
|
0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */,
|
||||||
|
D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */,
|
||||||
0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */,
|
0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */,
|
||||||
94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */,
|
94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */,
|
||||||
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */,
|
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */,
|
||||||
|
|||||||
@ -26,6 +26,10 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
|||||||
/// Closure passed here will run upon dismissing the selection picker.
|
/// Closure passed here will run upon dismissing the selection picker.
|
||||||
public var observeDropdownSelection: ((String)->())?
|
public var observeDropdownSelection: ((String)->())?
|
||||||
|
|
||||||
|
public var itemDropdownEntryFieldModel: ItemDropdownEntryFieldModel? {
|
||||||
|
return model as? ItemDropdownEntryFieldModel
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -100,7 +104,7 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
|||||||
setPickerDelegates(delegate: self)
|
setPickerDelegates(delegate: self)
|
||||||
|
|
||||||
if let pickerView = pickerView {
|
if let pickerView = pickerView {
|
||||||
self.pickerView(pickerView, didSelectRow: 0, inComponent: 0)
|
self.pickerView(pickerView, didSelectRow: model.selectedIndex, inComponent: 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,6 +131,7 @@ extension ItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource {
|
|||||||
|
|
||||||
observeDropdownChange?(text ?? "", pickerData[row])
|
observeDropdownChange?(text ?? "", pickerData[row])
|
||||||
text = pickerData[row]
|
text = pickerData[row]
|
||||||
|
itemDropdownEntryFieldModel?.selectedIndex = row
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public var options: [String] = []
|
public var options: [String] = []
|
||||||
|
public var selectedIndex: Int = 0
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
@ -24,6 +25,7 @@
|
|||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case options
|
case options
|
||||||
|
case selectedIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -34,6 +36,7 @@
|
|||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
options = try typeContainer.decode([String].self, forKey: .options)
|
options = try typeContainer.decode([String].self, forKey: .options)
|
||||||
|
selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) ?? 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
@ -41,5 +44,6 @@
|
|||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
try container.encode(options, forKey: .options)
|
try container.encode(options, forKey: .options)
|
||||||
|
try container.encode(options, forKey: .selectedIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
|
||||||
@objc public protocol ObservingTextFieldDelegate: NSObjectProtocol {
|
@objc public protocol ObservingTextFieldDelegate {
|
||||||
/// Called when the entered text becomes valid based on the validation block
|
/// Called when the entered text becomes valid based on the validation block
|
||||||
@objc optional func isValid(textfield: TextEntryField?)
|
@objc optional func isValid(textfield: TextEntryField?)
|
||||||
/// Called when the entered text becomes invalid based on the validation block
|
/// Called when the entered text becomes invalid based on the validation block
|
||||||
@ -85,7 +85,10 @@ import UIKit
|
|||||||
/// The text of this TextField.
|
/// The text of this TextField.
|
||||||
open override var text: String? {
|
open override var text: String? {
|
||||||
get { return textField.text }
|
get { return textField.text }
|
||||||
set { textField.text = newValue }
|
set {
|
||||||
|
textField.text = newValue
|
||||||
|
(model as? TextEntryFieldModel)?.text = newValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Placeholder access for the TextField.
|
/// Placeholder access for the TextField.
|
||||||
|
|||||||
@ -17,6 +17,7 @@ public enum GraphStyle: String, Codable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class CircleProgressModel: MoleculeModelProtocol {
|
public class CircleProgressModel: MoleculeModelProtocol {
|
||||||
|
|
||||||
public static var identifier: String = "circleProgress"
|
public static var identifier: String = "circleProgress"
|
||||||
public var style: GraphStyle = .unlimited {
|
public var style: GraphStyle = .unlimited {
|
||||||
didSet {
|
didSet {
|
||||||
|
|||||||
@ -220,17 +220,27 @@ public typealias ActionBlock = () -> ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
|
||||||
clauses = []
|
clauses = []
|
||||||
guard let labelModel = model as? LabelModel else { return }
|
|
||||||
|
guard let labelModel = model as? LabelModel else {
|
||||||
|
text = ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
attributedText = nil
|
attributedText = nil
|
||||||
|
originalAttributedString = nil
|
||||||
text = labelModel.text
|
text = labelModel.text
|
||||||
Label.setLabel(self, withHTML: labelModel.html)
|
Label.setLabel(self, withHTML: labelModel.html)
|
||||||
|
|
||||||
let alignment = LabelAlignment(rawValue: labelModel.textAlignment ?? "")
|
let alignment = LabelAlignment(rawValue: labelModel.textAlignment ?? "")
|
||||||
switch alignment {
|
switch alignment {
|
||||||
case .center:
|
case .center:
|
||||||
textAlignment = .center
|
textAlignment = .center
|
||||||
|
|
||||||
case .right:
|
case .right:
|
||||||
textAlignment = .right
|
textAlignment = .right
|
||||||
|
|
||||||
default:
|
default:
|
||||||
textAlignment = .left
|
textAlignment = .left
|
||||||
}
|
}
|
||||||
@ -239,9 +249,11 @@ public typealias ActionBlock = () -> ()
|
|||||||
if let backgroundColor = labelModel.backgroundColor {
|
if let backgroundColor = labelModel.backgroundColor {
|
||||||
self.backgroundColor = backgroundColor.uiColor
|
self.backgroundColor = backgroundColor.uiColor
|
||||||
}
|
}
|
||||||
|
|
||||||
if let accessibilityText = labelModel.accessibilityText {
|
if let accessibilityText = labelModel.accessibilityText {
|
||||||
accessibilityLabel = accessibilityText
|
accessibilityLabel = accessibilityText
|
||||||
}
|
}
|
||||||
|
|
||||||
if let fontStyle = labelModel.fontStyle {
|
if let fontStyle = labelModel.fontStyle {
|
||||||
MFStyler.styleLabel(self, withStyle: fontStyle)
|
MFStyler.styleLabel(self, withStyle: fontStyle)
|
||||||
MFStyler.styleLabel(self, withStyle: fontStyle, genericScaling: false)
|
MFStyler.styleLabel(self, withStyle: fontStyle, genericScaling: false)
|
||||||
@ -264,19 +276,23 @@ public typealias ActionBlock = () -> ()
|
|||||||
|
|
||||||
if let attributes = labelModel.attributes, let labelText = text {
|
if let attributes = labelModel.attributes, let labelText = text {
|
||||||
let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: font.withSize(standardFontSize), NSAttributedString.Key.foregroundColor: textColor as UIColor])
|
let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: font.withSize(standardFontSize), NSAttributedString.Key.foregroundColor: textColor as UIColor])
|
||||||
|
|
||||||
for attribute in attributes {
|
for attribute in attributes {
|
||||||
let range = NSRange(location: attribute.location, length: attribute.length)
|
let range = NSRange(location: attribute.location, length: attribute.length)
|
||||||
switch attribute {
|
switch attribute {
|
||||||
case _ as LabelAttributeUnderlineModel:
|
case _ as LabelAttributeUnderlineModel:
|
||||||
attributedString.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range)
|
attributedString.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range)
|
||||||
|
|
||||||
case _ as LabelAttributeStrikeThroughModel:
|
case _ as LabelAttributeStrikeThroughModel:
|
||||||
attributedString.addAttribute(.strikethroughStyle, value: NSUnderlineStyle.thick.rawValue, range: range)
|
attributedString.addAttribute(.strikethroughStyle, value: NSUnderlineStyle.thick.rawValue, range: range)
|
||||||
attributedString.addAttribute(.baselineOffset, value: 0, range: range)
|
attributedString.addAttribute(.baselineOffset, value: 0, range: range)
|
||||||
|
|
||||||
case let colorAtt as LabelAttributeColorModel:
|
case let colorAtt as LabelAttributeColorModel:
|
||||||
if let colorHex = colorAtt.textColor, !colorHex.isEmpty {
|
if let colorHex = colorAtt.textColor, !colorHex.isEmpty {
|
||||||
attributedString.removeAttribute(.foregroundColor, range: range)
|
attributedString.removeAttribute(.foregroundColor, range: range)
|
||||||
attributedString.addAttribute(.foregroundColor, value: UIColor.mfGet(forHex: colorHex), range: range)
|
attributedString.addAttribute(.foregroundColor, value: UIColor.mfGet(forHex: colorHex), range: range)
|
||||||
}
|
}
|
||||||
|
|
||||||
case let imageAtt as LabelAttributeImageModel:
|
case let imageAtt as LabelAttributeImageModel:
|
||||||
var fontSize = font.pointSize
|
var fontSize = font.pointSize
|
||||||
if let attributeSize = imageAtt.size {
|
if let attributeSize = imageAtt.size {
|
||||||
@ -293,6 +309,7 @@ public typealias ActionBlock = () -> ()
|
|||||||
let mutableString = NSMutableAttributedString()
|
let mutableString = NSMutableAttributedString()
|
||||||
mutableString.append(NSAttributedString(attachment: imageAttachment))
|
mutableString.append(NSAttributedString(attachment: imageAttachment))
|
||||||
attributedString.insert(mutableString, at: imageAtt.location)
|
attributedString.insert(mutableString, at: imageAtt.location)
|
||||||
|
|
||||||
case let fontAtt as LabelAttributeFontModel:
|
case let fontAtt as LabelAttributeFontModel:
|
||||||
if let fontStyle = fontAtt.style {
|
if let fontStyle = fontAtt.style {
|
||||||
let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle)
|
let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle)
|
||||||
@ -320,6 +337,7 @@ public typealias ActionBlock = () -> ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
addActionAttributes(range: range, string: attributedString)
|
addActionAttributes(range: range, string: attributedString)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -381,8 +399,9 @@ public typealias ActionBlock = () -> ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let attributes = json?.optionalArrayForKey("attributes"), let labelText = label.text {
|
if let attributes = json?.optionalArrayForKey("attributes"), let labelText = label.text {
|
||||||
let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: mvmLabel?.font.withSize(mvmLabel!.standardFontSize) ?? label.font as UIFont,
|
let attributedString = NSMutableAttributedString(string: labelText,
|
||||||
NSAttributedString.Key.foregroundColor: label.textColor as UIColor])
|
attributes: [NSAttributedString.Key.font: mvmLabel?.font.withSize(mvmLabel!.standardFontSize) ?? label.font as UIFont,
|
||||||
|
NSAttributedString.Key.foregroundColor: label.textColor as UIColor])
|
||||||
for case let attribute as [String: Any] in attributes {
|
for case let attribute as [String: Any] in attributes {
|
||||||
guard let attributeType = attribute.optionalStringForKey(KeyType),
|
guard let attributeType = attribute.optionalStringForKey(KeyType),
|
||||||
let location = attribute["location"] as? Int,
|
let location = attribute["location"] as? Int,
|
||||||
@ -733,7 +752,6 @@ extension Label {
|
|||||||
|
|
||||||
/// Applied to existing text. Removes underlines of tappable links and assoated actionable clauses.
|
/// Applied to existing text. Removes underlines of tappable links and assoated actionable clauses.
|
||||||
@objc public func clearActionableClauses() {
|
@objc public func clearActionableClauses() {
|
||||||
|
|
||||||
guard let attributedText = attributedText else { return }
|
guard let attributedText = attributedText else { return }
|
||||||
let mutableAttributedString = NSMutableAttributedString(attributedString: attributedText)
|
let mutableAttributedString = NSMutableAttributedString(attributedString: attributedText)
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,9 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@objcMembers public class LabelAttributeColorModel: LabelAttributeModel {
|
@objcMembers public class LabelAttributeColorModel: LabelAttributeModel {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
override public class var identifier: String {
|
override public class var identifier: String {
|
||||||
return "color"
|
return "color"
|
||||||
@ -16,14 +19,21 @@ import UIKit
|
|||||||
|
|
||||||
var textColor: String?
|
var textColor: String?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Keys
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case textColor
|
case textColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codec
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
|
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
self.textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor)
|
textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor)
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,12 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class LabelAttributeFontModel: LabelAttributeModel {
|
@objcMembers public class LabelAttributeFontModel: LabelAttributeModel {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
override public class var identifier: String {
|
override public class var identifier: String {
|
||||||
return "font"
|
return "font"
|
||||||
}
|
}
|
||||||
@ -17,17 +22,25 @@ import UIKit
|
|||||||
var name: String?
|
var name: String?
|
||||||
var size: CGFloat?
|
var size: CGFloat?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Keys
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case style
|
case style
|
||||||
case name
|
case name
|
||||||
case size
|
case size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codec
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
self.style = try typeContainer.decodeIfPresent(String.self, forKey: .style)
|
style = try typeContainer.decodeIfPresent(String.self, forKey: .style)
|
||||||
self.name = try typeContainer.decodeIfPresent(String.self, forKey: .name)
|
name = try typeContainer.decodeIfPresent(String.self, forKey: .name)
|
||||||
self.size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size)
|
size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size)
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,10 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class LabelAttributeImageModel: LabelAttributeModel {
|
class LabelAttributeImageModel: LabelAttributeModel {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
override public class var identifier: String {
|
override public class var identifier: String {
|
||||||
return "image"
|
return "image"
|
||||||
}
|
}
|
||||||
@ -18,17 +21,25 @@ class LabelAttributeImageModel: LabelAttributeModel {
|
|||||||
var name: String?
|
var name: String?
|
||||||
var URL: String?
|
var URL: String?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Keys
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case size
|
case size
|
||||||
case name
|
case name
|
||||||
case URL
|
case URL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codec
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
self.size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size)
|
size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size)
|
||||||
self.name = try typeContainer.decodeIfPresent(String.self, forKey: .name)
|
name = try typeContainer.decodeIfPresent(String.self, forKey: .name)
|
||||||
self.URL = try typeContainer.decodeIfPresent(String.self, forKey: .URL)
|
URL = try typeContainer.decodeIfPresent(String.self, forKey: .URL)
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,17 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers open class LabelAttributeModel: Model {
|
@objcMembers open class LabelAttributeModel: Model {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public static var categoryName: String {
|
||||||
|
return "\(LabelAttributeModel.self)"
|
||||||
|
}
|
||||||
|
|
||||||
|
public static var categoryCodingKey: String {
|
||||||
|
return "type"
|
||||||
|
}
|
||||||
|
|
||||||
public class var identifier: String {
|
public class var identifier: String {
|
||||||
return ""
|
return ""
|
||||||
@ -18,17 +29,25 @@ import Foundation
|
|||||||
var location: Int
|
var location: Int
|
||||||
var length: Int
|
var length: Int
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Keys
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case type
|
case type
|
||||||
case location
|
case location
|
||||||
case length
|
case length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codec
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
self.type = try typeContainer.decode(String.self, forKey: .type)
|
type = try typeContainer.decode(String.self, forKey: .type)
|
||||||
self.location = try typeContainer.decode(Int.self, forKey: .location)
|
location = try typeContainer.decode(Int.self, forKey: .location)
|
||||||
self.length = try typeContainer.decode(Int.self, forKey: .length)
|
length = try typeContainer.decode(Int.self, forKey: .length)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -37,5 +56,4 @@ import Foundation
|
|||||||
try container.encode(location, forKey: .location)
|
try container.encode(location, forKey: .location)
|
||||||
try container.encode(length, forKey: .length)
|
try container.encode(length, forKey: .length)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,19 +48,19 @@ import Foundation
|
|||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
self.moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName)
|
moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName)
|
||||||
self.text = try typeContainer.decode(String.self, forKey: .text)
|
text = try typeContainer.decode(String.self, forKey: .text)
|
||||||
self.accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||||
self.textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor)
|
textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor)
|
||||||
self.backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
self.fontStyle = try typeContainer.decodeIfPresent(String.self, forKey: .fontStyle)
|
fontStyle = try typeContainer.decodeIfPresent(String.self, forKey: .fontStyle)
|
||||||
self.fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName)
|
fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName)
|
||||||
self.fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize)
|
fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize)
|
||||||
self.textAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .textAlignment)
|
textAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .textAlignment)
|
||||||
self.attributes = try typeContainer.decodeModelsIfPresent(codingKey: .attributes, typeCodingKey: AttributeTypeKey.type) as? [LabelAttributeModel]
|
attributes = try typeContainer.decodeModelsIfPresent(codingKey: .attributes, typeCodingKey: AttributeTypeKey.type) as? [LabelAttributeModel]
|
||||||
self.html = try typeContainer.decodeIfPresent(String.self, forKey: .html)
|
html = try typeContainer.decodeIfPresent(String.self, forKey: .html)
|
||||||
self.hero = try typeContainer.decodeIfPresent(Int.self, forKey: .hero)
|
hero = try typeContainer.decodeIfPresent(Int.self, forKey: .hero)
|
||||||
self.makeWholeViewClickable = try typeContainer.decodeIfPresent(Bool.self, forKey: .makeWholeViewClickable)
|
makeWholeViewClickable = try typeContainer.decodeIfPresent(Bool.self, forKey: .makeWholeViewClickable)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
|||||||
@ -357,6 +357,10 @@ import UIKit
|
|||||||
loadImage(withName: imageName, format: nil, width: width, height: height, customFallbackImage: nil, completionHandler: completionHandler)
|
loadImage(withName: imageName, format: nil, width: width, height: height, customFallbackImage: nil, completionHandler: completionHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func loadImage(withName imageName: String?, width: NSNumber?, height: NSNumber?, customFallbackImage: String?, completionHandler: @escaping MVMCoreGetImageBlock) {
|
||||||
|
loadImage(withName: imageName, format: nil, width: width, height: height, customFallbackImage: customFallbackImage, completionHandler: completionHandler)
|
||||||
|
}
|
||||||
|
|
||||||
public func loadImage(withName imageName: String?, format: String?, width: NSNumber?, height: NSNumber?, customFallbackImage: String?) {
|
public func loadImage(withName imageName: String?, format: String?, width: NSNumber?, height: NSNumber?, customFallbackImage: String?) {
|
||||||
loadImage(withName: imageName, format: format, width: width, height: height, customFallbackImage: customFallbackImage, completionHandler: defaultCompletionBlock())
|
loadImage(withName: imageName, format: format, width: width, height: height, customFallbackImage: customFallbackImage, completionHandler: defaultCompletionBlock())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,8 @@ import UIKit
|
|||||||
|
|
||||||
private var heroAccessoryCenter: CGPoint?
|
private var heroAccessoryCenter: CGPoint?
|
||||||
|
|
||||||
|
private var initialSetupPerformed = false
|
||||||
|
|
||||||
// MARK: - Styling
|
// MARK: - Styling
|
||||||
open func style(with styleString: String?) {
|
open func style(with styleString: String?) {
|
||||||
guard let styleString = styleString else {
|
guard let styleString = styleString else {
|
||||||
@ -102,12 +104,19 @@ import UIKit
|
|||||||
// MARK: - Inits
|
// MARK: - Inits
|
||||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
setupView()
|
initialSetup()
|
||||||
}
|
}
|
||||||
|
|
||||||
public required init?(coder aDecoder: NSCoder) {
|
public required init?(coder aDecoder: NSCoder) {
|
||||||
super.init(coder: aDecoder)
|
super.init(coder: aDecoder)
|
||||||
setupView()
|
initialSetup()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func initialSetup() {
|
||||||
|
if !initialSetupPerformed {
|
||||||
|
initialSetupPerformed = true
|
||||||
|
setupView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MFViewProtocol
|
// MARK: - MFViewProtocol
|
||||||
@ -151,10 +160,6 @@ import UIKit
|
|||||||
self.listItemModel = model
|
self.listItemModel = model
|
||||||
style(with: model.style)
|
style(with: model.style)
|
||||||
|
|
||||||
if let backgroundColor = model.backgroundColor {
|
|
||||||
self.backgroundColor = backgroundColor.uiColor
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the caret if there is an action and it's not declared hidden.
|
// Add the caret if there is an action and it's not declared hidden.
|
||||||
if !customAccessoryView {
|
if !customAccessoryView {
|
||||||
if let _ = model.action, !(model.hideArrow ?? false) {
|
if let _ = model.action, !(model.hideArrow ?? false) {
|
||||||
@ -169,11 +174,15 @@ import UIKit
|
|||||||
addSeparatorsIfNeeded()
|
addSeparatorsIfNeeded()
|
||||||
bottomSeparatorView?.setWithModel(separator, nil, nil)
|
bottomSeparatorView?.setWithModel(separator, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let moleculeModel = model as? MoleculeModelProtocol,
|
||||||
|
let backgroundColor = moleculeModel.backgroundColor {
|
||||||
|
self.backgroundColor = backgroundColor.uiColor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open func reset() {
|
open func reset() {
|
||||||
molecule?.reset?()
|
molecule?.reset?()
|
||||||
styleStandard()
|
|
||||||
backgroundColor = .white
|
backgroundColor = .white
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9,41 +9,35 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension MFViewController: MoleculeDelegateProtocol {
|
extension MFViewController: MoleculeDelegateProtocol {
|
||||||
public func getModuleWithName(_ name: String?) -> [AnyHashable : Any]? {
|
|
||||||
guard let name = name else {
|
public func getModuleWithName(_ name: String?) -> [AnyHashable: Any]? {
|
||||||
return nil
|
guard let name = name else { return nil }
|
||||||
}
|
|
||||||
return loadObject?.modulesJSON?.optionalDictionaryForKey(name)
|
return loadObject?.modulesJSON?.optionalDictionaryForKey(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getModuleWithName(_ moduleName: String) -> MoleculeModelProtocol? {
|
public func getModuleWithName(_ moleculeName: String) -> MoleculeModelProtocol? {
|
||||||
guard let moduleJSON = loadObject?.modulesJSON?.optionalDictionaryForKey(moduleName),
|
guard let moduleJSON = loadObject?.modulesJSON?.optionalDictionaryForKey(moleculeName),
|
||||||
let moleculeName = moduleJSON.optionalStringForKey("moleculeName"),
|
let moleculeName = moduleJSON.optionalStringForKey("moleculeName"),
|
||||||
let modelType = ModelRegistry.getType(for: moleculeName) as? MoleculeModelProtocol.Type else {
|
let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self)
|
||||||
return nil
|
else { return nil }
|
||||||
}
|
|
||||||
do {
|
do {
|
||||||
return try modelType.decode(jsonDict: moduleJSON)
|
return try modelType.decode(jsonDict: moduleJSON) as? MoleculeModelProtocol
|
||||||
} catch {
|
} catch {
|
||||||
MVMCoreUILoggingHandler.logDebugMessage(withDelegate: "error: \(error)")
|
MVMCoreUILoggingHandler.logDebugMessage(withDelegate: "error: \(error)")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) {
|
@objc public func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) { }
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func addMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
@objc public func addMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { }
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func removeMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
@objc public func removeMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { }
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension MFViewController {
|
public extension MFViewController {
|
||||||
@objc func parsePageJSON() throws {
|
@objc func parsePageJSON() throws { }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,9 +68,8 @@ open class ThreeLayerTableViewController: MFProgrammaticTableViewController {
|
|||||||
|
|
||||||
open override func updateViewConstraints() {
|
open override func updateViewConstraints() {
|
||||||
super.updateViewConstraints()
|
super.updateViewConstraints()
|
||||||
guard let tableView = tableView else {
|
|
||||||
return
|
guard let tableView = tableView else { return }
|
||||||
}
|
|
||||||
|
|
||||||
let minimumSpace: CGFloat = minimumFillSpace()
|
let minimumSpace: CGFloat = minimumFillSpace()
|
||||||
var currentSpace: CGFloat = 0
|
var currentSpace: CGFloat = 0
|
||||||
@ -90,9 +89,8 @@ open class ThreeLayerTableViewController: MFProgrammaticTableViewController {
|
|||||||
totalMinimumSpace += minimumSpace
|
totalMinimumSpace += minimumSpace
|
||||||
}
|
}
|
||||||
|
|
||||||
guard fillTop || fillBottom else {
|
guard fillTop || fillBottom else { return }
|
||||||
return
|
|
||||||
}
|
|
||||||
let newSpace = MVMCoreUIUtility.getVariableConstraintHeight(currentSpace, in: tableView, minimumHeight: totalMinimumSpace)
|
let newSpace = MVMCoreUIUtility.getVariableConstraintHeight(currentSpace, in: tableView, minimumHeight: totalMinimumSpace)
|
||||||
|
|
||||||
// If the bottom view is outside of the scroll, then only the top view constraint is being used, so we have to double it to account for the bottom constraint not being there when we compare to the new value.
|
// If the bottom view is outside of the scroll, then only the top view constraint is being used, so we have to double it to account for the bottom constraint not being there when we compare to the new value.
|
||||||
@ -168,6 +166,8 @@ open class ThreeLayerTableViewController: MFProgrammaticTableViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This extra view is needed because of the wonkiness of apple's table header. Things breaks if using autolayout.
|
// This extra view is needed because of the wonkiness of apple's table header. Things breaks if using autolayout.
|
||||||
|
headerView.setNeedsLayout()
|
||||||
|
headerView.layoutIfNeeded()
|
||||||
MVMCoreUIUtility.sizeView(toFit: headerView)
|
MVMCoreUIUtility.sizeView(toFit: headerView)
|
||||||
let tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: MVMCoreUIUtility.getWidth(), height: headerView.frame.height))
|
let tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: MVMCoreUIUtility.getWidth(), height: headerView.frame.height))
|
||||||
tableHeaderView.addSubview(headerView)
|
tableHeaderView.addSubview(headerView)
|
||||||
|
|||||||
82
MVMCoreUI/BaseControllers/ViewController.swift
Normal file
82
MVMCoreUI/BaseControllers/ViewController.swift
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
//
|
||||||
|
// ViewController.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 11/5/19.
|
||||||
|
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objcMembers open class ViewController: UIViewController, MVMCoreViewControllerProtocol {
|
||||||
|
public var pageType: String?
|
||||||
|
public var loadObject: MVMCoreLoadObject?
|
||||||
|
public var pageModel: PageModelProtocol?
|
||||||
|
|
||||||
|
// MARK: Response handling
|
||||||
|
public func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
|
||||||
|
pageType = loadObject.pageType
|
||||||
|
self.loadObject = loadObject
|
||||||
|
|
||||||
|
// Parse the model for the page.
|
||||||
|
do {
|
||||||
|
try parsePageJSON()
|
||||||
|
} catch let parsingError {
|
||||||
|
// Log all parsing errors and fail load.
|
||||||
|
if let errorObject = MVMCoreErrorObject.createErrorObject(for: parsingError, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject)) {
|
||||||
|
errorObject.messageToDisplay = MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess)
|
||||||
|
error.pointee = errorObject
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies all modules needed are loaded.
|
||||||
|
return MFViewController.verifyRequiredModulesLoaded(for: loadObject, error: error)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func parsePageJSON() throws {
|
||||||
|
}
|
||||||
|
|
||||||
|
public class func verifyRequiredModulesLoaded(for loadObject: MVMCoreLoadObject?, error: inout MVMCoreErrorObject?) -> Bool {
|
||||||
|
guard let pageType = loadObject?.pageType, var modulesRequired = MVMCoreUIViewControllerMappingObject.shared()?.modulesRequired(forPageType: pageType) else { return true }
|
||||||
|
|
||||||
|
guard let loadedModules = loadObject?.modulesJSON else { return false }
|
||||||
|
|
||||||
|
for case let key as String in Array(loadedModules.keys) {
|
||||||
|
guard modulesRequired.count > 0 else { break }
|
||||||
|
if let index = modulesRequired.firstIndex(where: {($0 as? String) == key}) {
|
||||||
|
modulesRequired.remove(at: index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
guard modulesRequired.count == 0 else {
|
||||||
|
if error != nil {
|
||||||
|
error = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorCritical), messageToLog: modulesRequired.description, code: ErrorCode.requiredModuleNotPresent.rawValue, domain: ErrorDomainNative, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject!))
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
open func setNavigationItem() {
|
||||||
|
navigationItem.title = pageModel?.screenHeading
|
||||||
|
navigationItem.accessibilityLabel = pageModel?.screenHeading
|
||||||
|
}
|
||||||
|
|
||||||
|
open func newDataBuildScreen() {
|
||||||
|
// TODO atomize the navigation item
|
||||||
|
setNavigationItem()
|
||||||
|
}
|
||||||
|
|
||||||
|
open func initialLoad() {
|
||||||
|
}
|
||||||
|
|
||||||
|
open func updateViews() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override open func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
// Do any additional setup after loading the view.
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -48,7 +48,8 @@ public class ContainerModel: ContainerModelProtocol, Codable {
|
|||||||
try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: horizontalAlignment), forKey: .horizontalAlignment)
|
try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: horizontalAlignment), forKey: .horizontalAlignment)
|
||||||
try container.encodeIfPresent(useHorizontalMargins, forKey: .useHorizontalMargins)
|
try container.encodeIfPresent(useHorizontalMargins, forKey: .useHorizontalMargins)
|
||||||
try container.encodeIfPresent(useVerticalMargins, forKey: .useVerticalMargins)
|
try container.encodeIfPresent(useVerticalMargins, forKey: .useVerticalMargins)
|
||||||
try container.encodeIfPresent(topMarginPadding, forKey: .topMarginPadding)
|
// TODO: can add this back once we have type erasures.
|
||||||
try container.encodeIfPresent(bottomMarginPadding, forKey: .bottomMarginPadding)
|
//try container.encodeIfPresent(topMarginPadding, forKey: .topMarginPadding)
|
||||||
|
//try container.encodeIfPresent(bottomMarginPadding, forKey: .bottomMarginPadding)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,9 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension KeyedDecodingContainer where Key : CodingKey {
|
|
||||||
|
extension KeyedDecodingContainer where Key: CodingKey {
|
||||||
|
|
||||||
private enum TypeCodingKey: String, CodingKey {
|
private enum TypeCodingKey: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
public protocol CarouselItemModelProtocol: ContainerModelProtocol, MoleculeModelProtocol {
|
public protocol CarouselItemModelProtocol: ContainerModelProtocol, MoleculeModelProtocol {
|
||||||
var peakingUI: Bool? {get}
|
var peakingUI: Bool? { get }
|
||||||
var peakingArrowColor: Color? {get}
|
var peakingArrowColor: Color? { get }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
public protocol ContainerModelProtocol {
|
public protocol ContainerModelProtocol {
|
||||||
var horizontalAlignment: UIStackView.Alignment? { get set }
|
var horizontalAlignment: UIStackView.Alignment? { get set }
|
||||||
var verticalAlignment: UIStackView.Alignment? { get set }
|
var verticalAlignment: UIStackView.Alignment? { get set }
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
public protocol EnableableModelProtocol {
|
public protocol EnableableModelProtocol {
|
||||||
var enabled: Bool { get set }
|
var enabled: Bool { get set }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
public protocol FormModelProtocol: Model {
|
public protocol FormModelProtocol: Model {
|
||||||
var required: Bool? { get }
|
var required: Bool? { get }
|
||||||
var fieldKey: String? { get }
|
var fieldKey: String? { get }
|
||||||
|
|||||||
@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol ListItemModelProtocol: ContainerModelProtocol, MoleculeModelProtocol {
|
|
||||||
|
public protocol ListItemModelProtocol: ContainerModelProtocol {
|
||||||
var line: LineModel? { get set }
|
var line: LineModel? { get set }
|
||||||
var action: ActionModelProtocol? { get set }
|
var action: ActionModelProtocol? { get set }
|
||||||
var hideArrow: Bool? { get set }
|
var hideArrow: Bool? { get set }
|
||||||
@ -16,20 +17,15 @@ public protocol ListItemModelProtocol: ContainerModelProtocol, MoleculeModelProt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not a strict requirement.
|
// Not a strict requirement.
|
||||||
extension ListItemModelProtocol {
|
public extension ListItemModelProtocol {
|
||||||
public var action: ActionModelProtocol? {
|
|
||||||
get {
|
var action: ActionModelProtocol? {
|
||||||
return nil
|
get { return nil }
|
||||||
}
|
set { }
|
||||||
set {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var style: String? {
|
var style: String? {
|
||||||
get {
|
get { return nil }
|
||||||
return nil
|
set { }
|
||||||
}
|
|
||||||
set {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,22 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
public protocol MoleculeModelProtocol: Model {
|
public protocol MoleculeModelProtocol: Model {
|
||||||
var moleculeName: String? { get }
|
var moleculeName: String? { get }
|
||||||
var backgroundColor: Color? { get set}
|
var backgroundColor: Color? { get set}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MoleculeModelProtocol {
|
public extension MoleculeModelProtocol {
|
||||||
public var moleculeName: String? {
|
|
||||||
|
var moleculeName: String? {
|
||||||
get { return Self.identifier }
|
get { return Self.identifier }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static var categoryName: String {
|
||||||
|
return "\(MoleculeModelProtocol.self)"
|
||||||
|
}
|
||||||
|
|
||||||
|
static var categoryCodingKey: String {
|
||||||
|
return "moleculeName"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol PageModelProtocol: Model {
|
|
||||||
|
public protocol PageModelProtocol {
|
||||||
var pageType: String { get set }
|
var pageType: String { get set }
|
||||||
var screenHeading: String? { get set }
|
var screenHeading: String? { get set }
|
||||||
var isAtomicTabs: Bool? { get set }
|
var isAtomicTabs: Bool? { get set }
|
||||||
|
|||||||
@ -8,12 +8,22 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol TemplateModelProtocol: PageModelProtocol {
|
|
||||||
|
public protocol TemplateModelProtocol: PageModelProtocol, Model {
|
||||||
var template: String { get }
|
var template: String { get }
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TemplateModelProtocol {
|
public extension TemplateModelProtocol {
|
||||||
public var template: String {
|
|
||||||
|
var template: String {
|
||||||
get { return Self.identifier }
|
get { return Self.identifier }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static var categoryCodingKey: String {
|
||||||
|
return "template"
|
||||||
|
}
|
||||||
|
|
||||||
|
static var categoryName: String {
|
||||||
|
return "\(TemplateModelProtocol.self)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,71 @@
|
|||||||
|
//
|
||||||
|
// ListLeftVariableIconWithRightCaret.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kruthika KP on 03/02/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objcMembers public class ListLeftVariableIconWithRightCaret: TableViewCell {
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Outlets
|
||||||
|
//-------------------------------------------------------
|
||||||
|
let leftImage = MFLoadImageView(pinnedEdges: .all)
|
||||||
|
let leftLabel = Label.commonLabelB2(true)
|
||||||
|
let rightLabel = Label.commonLabelB2(true)
|
||||||
|
let stack = Stack<StackModel>(frame: .zero)
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - View Lifecycle
|
||||||
|
//-------------------------------------------------------
|
||||||
|
open override func updateView(_ size: CGFloat) {
|
||||||
|
super.updateView(size)
|
||||||
|
stack.updateView(size)
|
||||||
|
}
|
||||||
|
|
||||||
|
override open func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
stack.stackItems = [StackItem(andContain: leftImage),StackItem(andContain: leftLabel),StackItem(andContain: rightLabel)]
|
||||||
|
contentView.addSubview(stack)
|
||||||
|
containerHelper.constrainView(stack)
|
||||||
|
leftLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 901), for: .horizontal)
|
||||||
|
rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 902), for: .horizontal)
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------
|
||||||
|
// MARK: - Molecule
|
||||||
|
//------------------------------------------------------
|
||||||
|
override open func reset() {
|
||||||
|
super.reset()
|
||||||
|
stack.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
|
super.setWithModel(model, delegateObject, additionalData)
|
||||||
|
guard let model = model as? ListLeftVariableIconWithRightCaretModel else { return}
|
||||||
|
leftImage.setWithModel(model.image, delegateObject, additionalData)
|
||||||
|
leftLabel.setWithModel(model.leftLabel, delegateObject, additionalData)
|
||||||
|
rightLabel.setWithModel(model.rightLabel, delegateObject, additionalData)
|
||||||
|
|
||||||
|
// Create a stack model to use for the internal stack and set the alignment of labels
|
||||||
|
let leftImage = StackItemModel()
|
||||||
|
leftImage.horizontalAlignment = .fill
|
||||||
|
let leftLabel = StackItemModel()
|
||||||
|
leftLabel.horizontalAlignment = .fill
|
||||||
|
let rightLabel = StackItemModel()
|
||||||
|
rightLabel.horizontalAlignment = .trailing
|
||||||
|
let stackModel = StackModel(molecules: [leftImage,leftLabel,rightLabel])
|
||||||
|
stackModel.axis = .horizontal
|
||||||
|
stack.model = stackModel
|
||||||
|
stack.restack()
|
||||||
|
}
|
||||||
|
|
||||||
|
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
return 90
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// ListLeftVariableIconWithRightCaretModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kruthika KP on 03/02/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class ListLeftVariableIconWithRightCaretModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "listLVImg"
|
||||||
|
public var image: ImageViewModel
|
||||||
|
public var leftLabel: LabelModel
|
||||||
|
public var rightLabel: LabelModel
|
||||||
|
|
||||||
|
override public func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
|
if image.height == nil {
|
||||||
|
image.height = 30.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(image: ImageViewModel, leftLabel: LabelModel, rightLabel: LabelModel) {
|
||||||
|
self.image = image
|
||||||
|
self.leftLabel = leftLabel
|
||||||
|
self.rightLabel = rightLabel
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case leftLabel
|
||||||
|
case rightLabel
|
||||||
|
case image
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel)
|
||||||
|
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
|
||||||
|
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
||||||
|
try super.init(from: decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func encode(to encoder: Encoder) throws {
|
||||||
|
try super.encode(to: encoder)
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
|
try container.encode(leftLabel, forKey: .leftLabel)
|
||||||
|
try container.encode(rightLabel, forKey: .rightLabel)
|
||||||
|
try container.encode(image, forKey: .image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// ThreeColumnPlanDataDividerList.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Acharya, Subhankar on 04/02/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers open class ListThreeColumnPlanDataDivider: TableViewCell {
|
||||||
|
|
||||||
|
let leftHeadlineBody = HeadlineBody(frame: .zero)
|
||||||
|
let centerHeadLineBody = HeadlineBody(frame: .zero)
|
||||||
|
let rightHeadLineBody = HeadlineBody(frame: .zero)
|
||||||
|
let stack = Stack<StackModel>(frame: .zero)
|
||||||
|
|
||||||
|
// MARK: - MFViewProtocol
|
||||||
|
open override func updateView(_ size: CGFloat) {
|
||||||
|
super.updateView(size)
|
||||||
|
stack.updateView(size)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
|
||||||
|
//using stackItems to align the three headlineBody
|
||||||
|
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
stack.stackItems = [StackItem(andContain: leftHeadlineBody),StackItem(andContain: centerHeadLineBody),StackItem(andContain: rightHeadLineBody)]
|
||||||
|
contentView.addSubview(stack)
|
||||||
|
containerHelper.constrainView(stack)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||||
|
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
|
super.setWithModel(model, delegateObject, additionalData)
|
||||||
|
guard let model = model as? ListThreeColumnPlanDataDividerModel else { return }
|
||||||
|
leftHeadlineBody.setWithModel(model.leftHeadlineBody, delegateObject, additionalData)
|
||||||
|
centerHeadLineBody.setWithModel(model.centerHeadlineBody, delegateObject, additionalData)
|
||||||
|
rightHeadLineBody.setWithModel(model.rightHeadlineBody, delegateObject, additionalData)
|
||||||
|
|
||||||
|
// Create a stack model to use for the internal stack and set the alignment of models
|
||||||
|
let leftHeadlineBodyAlignment = StackItemModel(percent: 33)
|
||||||
|
leftHeadlineBodyAlignment.horizontalAlignment = .leading
|
||||||
|
let centerHeadLineBodyAlignment = StackItemModel(percent: 34)
|
||||||
|
centerHeadLineBodyAlignment.horizontalAlignment = .center
|
||||||
|
let rightHeadLineBodyAlignment = StackItemModel(percent: 33)
|
||||||
|
rightHeadLineBodyAlignment.horizontalAlignment = .trailing
|
||||||
|
let stackModel = StackModel(molecules: [leftHeadlineBodyAlignment,centerHeadLineBodyAlignment,rightHeadLineBodyAlignment])
|
||||||
|
stackModel.axis = .horizontal
|
||||||
|
stack.model = stackModel
|
||||||
|
stack.restack()
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func reset() {
|
||||||
|
super.reset()
|
||||||
|
stack.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||||
|
return 121
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// ThreeColumnPlanDataDividerListModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Acharya, Subhankar on 04/02/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
public class ListThreeColumnPlanDataDividerModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "list3CHBDiv"
|
||||||
|
public var leftHeadlineBody: HeadlineBodyModel
|
||||||
|
public var centerHeadlineBody: HeadlineBodyModel
|
||||||
|
public var rightHeadlineBody: HeadlineBodyModel
|
||||||
|
|
||||||
|
public init(leftHeadlineBody: HeadlineBodyModel, centerHeadlineBody:HeadlineBodyModel, rightHeadlineBody: HeadlineBodyModel) {
|
||||||
|
self.leftHeadlineBody = leftHeadlineBody
|
||||||
|
self.centerHeadlineBody = centerHeadlineBody
|
||||||
|
self.rightHeadlineBody = rightHeadlineBody
|
||||||
|
super.init()
|
||||||
|
setDefaults()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defaults to set
|
||||||
|
override public func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
|
style = "tallDivider"
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case leftHeadlineBody
|
||||||
|
case centerHeadlineBody
|
||||||
|
case rightHeadlineBody
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
leftHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .leftHeadlineBody)
|
||||||
|
centerHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .centerHeadlineBody)
|
||||||
|
rightHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .rightHeadlineBody)
|
||||||
|
try super.init(from: decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func encode(to encoder: Encoder) throws {
|
||||||
|
try super.encode(to: encoder)
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
|
try container.encode(leftHeadlineBody, forKey: .leftHeadlineBody)
|
||||||
|
try container.encode(centerHeadlineBody, forKey: .centerHeadlineBody)
|
||||||
|
try container.encode(rightHeadlineBody, forKey: .rightHeadlineBody)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -8,28 +8,31 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class AccordionListItemModel: MoleculeContainerModel, ListItemModelProtocol {
|
class AccordionListItemModel: MoleculeListItemModel {
|
||||||
public static var identifier: String = "accordionListItem"
|
override public class var identifier: String {
|
||||||
public var molecules: [ListItemModelProtocol]
|
return "accordionListItem"
|
||||||
public var backgroundColor: Color?
|
}
|
||||||
|
public var molecules: [ListItemModelProtocol & MoleculeModelProtocol]
|
||||||
public var hideLineWhenExpanded: Bool = false
|
public var hideLineWhenExpanded: Bool = false
|
||||||
public var hideArrow: Bool? = true
|
|
||||||
public var line: LineModel?
|
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case molecules
|
case molecules
|
||||||
case backgroundColor
|
case molecule
|
||||||
case hideLineWhenExpanded
|
case hideLineWhenExpanded
|
||||||
case hideArrow
|
}
|
||||||
case line
|
|
||||||
|
public override func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
|
hideArrow = true
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
molecules = try typeContainer.decodeMolecules(codingKey: .molecules) as! [ListItemModelProtocol]
|
guard let molecules = try typeContainer.decodeMolecules(codingKey: .molecules) as? [ListItemModelProtocol & MoleculeModelProtocol] else {
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
throw DecodingError.typeMismatch([ListItemModelProtocol & MoleculeModelProtocol].self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Casting failed"))
|
||||||
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
}
|
||||||
|
self.molecules = molecules
|
||||||
if let hideLine = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideLineWhenExpanded) {
|
if let hideLine = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideLineWhenExpanded) {
|
||||||
hideLineWhenExpanded = hideLine
|
hideLineWhenExpanded = hideLine
|
||||||
}
|
}
|
||||||
@ -41,8 +44,6 @@ class AccordionListItemModel: MoleculeContainerModel, ListItemModelProtocol {
|
|||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
try container.encodeModels(molecules, forKey: .molecules)
|
try container.encodeModels(molecules, forKey: .molecules)
|
||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
|
||||||
try container.encodeIfPresent(hideLineWhenExpanded, forKey: .hideLineWhenExpanded)
|
try container.encodeIfPresent(hideLineWhenExpanded, forKey: .hideLineWhenExpanded)
|
||||||
try container.encodeIfPresent(line, forKey: .line)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,9 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@objcMembers public class AccordionMoleculeTableViewCell: MoleculeTableViewCell {
|
@objcMembers public class AccordionMoleculeTableViewCell: MoleculeTableViewCell {
|
||||||
var accordionListItemModel: AccordionListItemModel?
|
var accordionListItemModel: AccordionListItemModel? {
|
||||||
|
return listItemModel as? AccordionListItemModel
|
||||||
|
}
|
||||||
let accordionButton = createAccordionButton()
|
let accordionButton = createAccordionButton()
|
||||||
|
|
||||||
static func createAccordionButton() -> MFCustomButton {
|
static func createAccordionButton() -> MFCustomButton {
|
||||||
@ -30,10 +32,14 @@ import UIKit
|
|||||||
override public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
override public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||||
accordionButton.isSelected = !accordionButton.isSelected
|
accordionButton.isSelected = !accordionButton.isSelected
|
||||||
accordionButton.setTitle(accordionButton.isSelected ? "-" : "+", for: .normal)
|
accordionButton.setTitle(accordionButton.isSelected ? "-" : "+", for: .normal)
|
||||||
guard let molecules = accordionListItemModel?.molecules else {
|
guard let model = accordionListItemModel else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guard let json = model.toJSON(),
|
||||||
|
let molecules = json.optionalArrayForKey("molecules") as? [[AnyHashable: Any]]
|
||||||
|
else { return }
|
||||||
|
|
||||||
if accordionButton.isSelected {
|
if accordionButton.isSelected {
|
||||||
delegateObject?.moleculeDelegate?.addMolecules(molecules, sender: self, animation: .automatic)
|
delegateObject?.moleculeDelegate?.addMolecules(molecules, sender: self, animation: .automatic)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -24,8 +24,7 @@ import UIKit
|
|||||||
|
|
||||||
override public func setupView() {
|
override public func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
|
|
||||||
guard dropDown.superview == nil else { return }
|
|
||||||
addMolecule(dropDown)
|
addMolecule(dropDown)
|
||||||
dropDown.observeDropdownChange = { [weak self] oldValue, newValue in
|
dropDown.observeDropdownChange = { [weak self] oldValue, newValue in
|
||||||
|
|
||||||
|
|||||||
@ -8,43 +8,31 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class DropDownListItemModel: ContainerModel, ListItemModelProtocol {
|
@objcMembers public class DropDownListItemModel: ListItemModel, MoleculeModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public static var identifier: String = "dropDownListItem"
|
public static var identifier: String = "dropDownListItem"
|
||||||
public var molecules: [[ListItemModelProtocol]]
|
public var molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]
|
||||||
public var dropDown: ItemDropdownEntryFieldModel
|
public var dropDown: ItemDropdownEntryFieldModel
|
||||||
public var backgroundColor: Color?
|
|
||||||
public var line: LineModel? = LineModel(type: .none)
|
|
||||||
public var hideArrow: Bool? = true
|
|
||||||
|
|
||||||
/// Defaults to set
|
/// Defaults to set
|
||||||
func setDefaults() {
|
public override func setDefaults() {
|
||||||
if useHorizontalMargins == nil {
|
super.setDefaults()
|
||||||
useHorizontalMargins = true
|
hideArrow = true
|
||||||
}
|
line = LineModel(type: .none)
|
||||||
if useVerticalMargins == nil {
|
style = "sectionFooter"
|
||||||
useVerticalMargins = true
|
|
||||||
}
|
|
||||||
if topMarginPadding == nil {
|
|
||||||
topMarginPadding = 24
|
|
||||||
}
|
|
||||||
if bottomMarginPadding == nil {
|
|
||||||
bottomMarginPadding = 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializer
|
// MARK: - Initializer
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public init(molecules: [[ListItemModelProtocol]], dropDown: ItemDropdownEntryFieldModel) {
|
public init(molecules: [[ListItemModelProtocol & MoleculeModelProtocol]], dropDown: ItemDropdownEntryFieldModel) {
|
||||||
self.molecules = molecules
|
self.molecules = molecules
|
||||||
self.dropDown = dropDown
|
self.dropDown = dropDown
|
||||||
super.init()
|
super.init()
|
||||||
setDefaults()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -55,8 +43,6 @@ import Foundation
|
|||||||
case moleculeName
|
case moleculeName
|
||||||
case molecules
|
case molecules
|
||||||
case dropDown
|
case dropDown
|
||||||
case line
|
|
||||||
case backgroundColor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -65,16 +51,9 @@ import Foundation
|
|||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
molecules = try typeContainer.decodeMolecules2D(codingKey: .molecules) as? [[ListItemModelProtocol]] ?? [[]]
|
molecules = try typeContainer.decodeMolecules2D(codingKey: .molecules) as? [[ListItemModelProtocol & MoleculeModelProtocol]] ?? [[]]
|
||||||
dropDown = try typeContainer.decode(ItemDropdownEntryFieldModel.self, forKey: .dropDown)
|
dropDown = try typeContainer.decode(ItemDropdownEntryFieldModel.self, forKey: .dropDown)
|
||||||
|
|
||||||
if let lineModel = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) {
|
|
||||||
line = lineModel
|
|
||||||
}
|
|
||||||
|
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
setDefaults()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
@ -83,7 +62,5 @@ import Foundation
|
|||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
try container.encodeModels2D(molecules, forKey: .molecules)
|
try container.encodeModels2D(molecules, forKey: .molecules)
|
||||||
try container.encode(dropDown, forKey: .dropDown)
|
try container.encode(dropDown, forKey: .dropDown)
|
||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
|
||||||
try container.encodeIfPresent(line, forKey: .line)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,25 +1,22 @@
|
|||||||
//
|
//
|
||||||
// ListItem.swift
|
// BaseListItemModel.swift
|
||||||
// MVMCoreUI
|
// MVMCoreUI
|
||||||
//
|
//
|
||||||
// Created by Suresh, Kamlesh on 10/3/19.
|
// Created by Scott Pfeil on 2/12/20.
|
||||||
// Copyright © 2019 Suresh, Kamlesh. All rights reserved.
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
//
|
//
|
||||||
|
// A base class that has common list item boilerplate model stuffs.
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import MVMCore
|
|
||||||
|
|
||||||
@objcMembers public class ListItemModel: MoleculeContainerModel, ListItemModelProtocol {
|
@objcMembers public class ListItemModel: ContainerModel, ListItemModelProtocol {
|
||||||
|
|
||||||
public static var identifier: String = "listItem"
|
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var action: ActionModelProtocol?
|
public var action: ActionModelProtocol?
|
||||||
public var hideArrow: Bool?
|
public var hideArrow: Bool?
|
||||||
public var line: LineModel?
|
public var line: LineModel?
|
||||||
public var style: String? = "standard"
|
public var style: String?
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
|
||||||
case backgroundColor
|
case backgroundColor
|
||||||
case action
|
case action
|
||||||
case hideArrow
|
case hideArrow
|
||||||
@ -28,23 +25,20 @@ import MVMCore
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Defaults to set
|
/// Defaults to set
|
||||||
func setDefaults() {
|
public func setDefaults() {
|
||||||
if useHorizontalMargins == nil {
|
if useHorizontalMargins == nil {
|
||||||
useHorizontalMargins = true
|
useHorizontalMargins = true
|
||||||
}
|
}
|
||||||
if useVerticalMargins == nil {
|
if useVerticalMargins == nil {
|
||||||
useVerticalMargins = true
|
useVerticalMargins = true
|
||||||
}
|
}
|
||||||
if topMarginPadding == nil {
|
if style == nil {
|
||||||
topMarginPadding = 24
|
style = "standard"
|
||||||
}
|
|
||||||
if bottomMarginPadding == nil {
|
|
||||||
bottomMarginPadding = 24
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override init(with moleculeModel: MoleculeModelProtocol) {
|
public override init() {
|
||||||
super.init(with: moleculeModel)
|
super.init()
|
||||||
setDefaults()
|
setDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,9 +48,7 @@ import MVMCore
|
|||||||
action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType)
|
action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType)
|
||||||
hideArrow = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideArrow)
|
hideArrow = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideArrow)
|
||||||
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
||||||
if let style = try typeContainer.decodeIfPresent(String.self, forKey: .style) {
|
style = try typeContainer.decodeIfPresent(String.self, forKey: .style)
|
||||||
self.style = style
|
|
||||||
}
|
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
setDefaults()
|
setDefaults()
|
||||||
}
|
}
|
||||||
@ -64,7 +56,6 @@ import MVMCore
|
|||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
|
||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
try container.encodeModelIfPresent(action, forKey: .action)
|
try container.encodeModelIfPresent(action, forKey: .action)
|
||||||
try container.encodeIfPresent(hideArrow, forKey: .hideArrow)
|
try container.encodeIfPresent(hideArrow, forKey: .hideArrow)
|
||||||
|
|||||||
41
MVMCoreUI/Molecules/Items/MoleculeListItemModel.swift
Normal file
41
MVMCoreUI/Molecules/Items/MoleculeListItemModel.swift
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// ListItem.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Suresh, Kamlesh on 10/3/19.
|
||||||
|
// Copyright © 2019 Suresh, Kamlesh. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import MVMCore
|
||||||
|
|
||||||
|
@objcMembers public class MoleculeListItemModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
public class var identifier: String {
|
||||||
|
return "listItem"
|
||||||
|
}
|
||||||
|
public var molecule: MoleculeModelProtocol
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case molecule
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(with moleculeModel: MoleculeModelProtocol) {
|
||||||
|
molecule = moleculeModel
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
molecule = try typeContainer.decodeMolecule(codingKey: .molecule)
|
||||||
|
try super.init(from: decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func encode(to encoder: Encoder) throws {
|
||||||
|
try super.encode(to: encoder)
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
|
try container.encodeModel(molecule, forKey: .molecule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -8,14 +8,19 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
|
||||||
@objcMembers open class MoleculeTableViewCell: TableViewCell {
|
@objcMembers open class MoleculeTableViewCell: TableViewCell {
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||||
|
|
||||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.setWithModel(model, delegateObject, additionalData)
|
super.setWithModel(model, delegateObject, additionalData)
|
||||||
guard let model = model as? ListItemModel else { return }
|
|
||||||
|
guard let model = model as? MoleculeListItemModel else { return }
|
||||||
|
|
||||||
if molecule != nil {
|
if molecule != nil {
|
||||||
(molecule as? ModelMoleculeViewProtocol)?.setWithModel(model.molecule, delegateObject, additionalData)
|
(molecule as? ModelMoleculeViewProtocol)?.setWithModel(model.molecule, delegateObject, additionalData)
|
||||||
|
|
||||||
} else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(model.molecule, delegateObject, false) {
|
} else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(model.molecule, delegateObject, false) {
|
||||||
addMolecule(moleculeView)
|
addMolecule(moleculeView)
|
||||||
}
|
}
|
||||||
@ -24,28 +29,28 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
public override class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||||
guard let moleculeModel = (model as? ListItemModel)?.molecule else {
|
guard let moleculeModel = (model as? MoleculeListItemModel)?.molecule else { return "\(self)<>" }
|
||||||
return "\(self)<>"
|
|
||||||
}
|
|
||||||
let className = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type
|
let className = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type
|
||||||
let moleculeName = className?.nameForReuse(moleculeModel, delegateObject) ?? moleculeModel.moleculeName ?? ""
|
let moleculeName = className?.nameForReuse(moleculeModel, delegateObject) ?? moleculeModel.moleculeName ?? ""
|
||||||
|
|
||||||
return "\(self)<\(moleculeName)>"
|
return "\(self)<\(moleculeName)>"
|
||||||
}
|
}
|
||||||
|
|
||||||
public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
||||||
guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule),
|
guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule),
|
||||||
let theClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON) else {
|
let theClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON)
|
||||||
return nil
|
else { return nil }
|
||||||
}
|
|
||||||
return theClass.requiredModules?(moleculeJSON, delegateObject: delegateObject, error: error)
|
return theClass.requiredModules?(moleculeJSON, delegateObject: delegateObject, error: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||||
guard let moleculeModel = (molecule as? MoleculeContainerModel)?.molecule,
|
guard let moleculeModel = (molecule as? MoleculeContainerModel)?.molecule,
|
||||||
let classType = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type,
|
let classType = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type,
|
||||||
let height = classType.estimatedHeight(forRow: moleculeModel, delegateObject: delegateObject) else {
|
let height = classType.estimatedHeight(forRow: moleculeModel, delegateObject: delegateObject)
|
||||||
return 80
|
else { return 80 }
|
||||||
}
|
|
||||||
return max(2 * PaddingDefaultVerticalSpacing3, height)
|
return max(2 * PaddingDefaultVerticalSpacing3, height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class StackItemModel: StackItemModelProtocol, MoleculeModelProtocol {
|
@objcMembers public class StackItemModel: ContainerModel, StackItemModelProtocol, MoleculeModelProtocol {
|
||||||
public static var identifier: String = "simpleStackItem"
|
public static var identifier: String = "simpleStackItem"
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var spacing: CGFloat?
|
public var spacing: CGFloat?
|
||||||
@ -19,4 +19,9 @@ import Foundation
|
|||||||
self.init()
|
self.init()
|
||||||
self.gone = gone
|
self.gone = gone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public convenience init(percent: Int) {
|
||||||
|
self.init()
|
||||||
|
self.percent = percent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,39 +8,36 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
public class TabsListItemModel: ContainerModel, ListItemModelProtocol {
|
public class TabsListItemModel: ListItemModel, MoleculeModelProtocol {
|
||||||
public static var identifier: String = "tabsListItem"
|
public static var identifier: String = "tabsListItem"
|
||||||
var tabs: TabsModel
|
var tabs: TabsModel
|
||||||
var molecules: [[ListItemModelProtocol]]
|
var molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]
|
||||||
|
|
||||||
public var backgroundColor: Color?
|
|
||||||
public var hideArrow: Bool? = true
|
|
||||||
public var line: LineModel? = LineModel(type: .standard)
|
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case tabs
|
case tabs
|
||||||
case molecules
|
case molecules
|
||||||
case backgroundColor
|
|
||||||
case line
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(with tabs: TabsModel, molecules: [[ListItemModelProtocol]]) {
|
public override func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
|
hideArrow = true
|
||||||
|
action = nil
|
||||||
|
style = nil
|
||||||
|
topMarginPadding = 8
|
||||||
|
bottomMarginPadding = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(with tabs: TabsModel, molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]) {
|
||||||
self.tabs = tabs
|
self.tabs = tabs
|
||||||
self.molecules = molecules
|
self.molecules = molecules
|
||||||
super.init()
|
super.init()
|
||||||
self.topMarginPadding = 8
|
|
||||||
self.bottomMarginPadding = 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
tabs = try typeContainer.decode(TabsModel.self, forKey: .tabs)
|
tabs = try typeContainer.decode(TabsModel.self, forKey: .tabs)
|
||||||
molecules = try typeContainer.decodeMolecules2D(codingKey: .molecules) as! [[ListItemModelProtocol]]
|
molecules = try typeContainer.decodeMolecules2D(codingKey: .molecules) as! [[ListItemModelProtocol & MoleculeModelProtocol]]
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
|
||||||
if let lineModel = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) {
|
|
||||||
line = lineModel
|
|
||||||
}
|
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +47,5 @@ public class TabsListItemModel: ContainerModel, ListItemModelProtocol {
|
|||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
try container.encode(tabs, forKey: .tabs)
|
try container.encode(tabs, forKey: .tabs)
|
||||||
try container.encodeModels2D(molecules, forKey: .molecules)
|
try container.encodeModels2D(molecules, forKey: .molecules)
|
||||||
try container.encode(backgroundColor, forKey: .backgroundColor)
|
|
||||||
try container.encodeIfPresent(line, forKey: .line)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,9 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@objcMembers public class TabsTableViewCell: TableViewCell {
|
@objcMembers public class TabsTableViewCell: TableViewCell {
|
||||||
var tabsListItemModel: TabsListItemModel?
|
var tabsListItemModel: TabsListItemModel? {
|
||||||
|
return listItemModel as? TabsListItemModel
|
||||||
|
}
|
||||||
let tabs = TopTabbar(frame: .zero)
|
let tabs = TopTabbar(frame: .zero)
|
||||||
var delegateObject: MVMCoreUIDelegateObject?
|
var delegateObject: MVMCoreUIDelegateObject?
|
||||||
var previousTabIndex = 0
|
var previousTabIndex = 0
|
||||||
@ -17,11 +19,7 @@ import UIKit
|
|||||||
// MARK: - MFViewProtocol
|
// MARK: - MFViewProtocol
|
||||||
override public func setupView() {
|
override public func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
guard tabs.superview == nil else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tabs.paddingBeforeFirstTab = false
|
tabs.paddingBeforeFirstTab = false
|
||||||
|
|
||||||
tabs.translatesAutoresizingMaskIntoConstraints = false
|
tabs.translatesAutoresizingMaskIntoConstraints = false
|
||||||
tabs.delegate = self
|
tabs.delegate = self
|
||||||
tabs.datasource = self
|
tabs.datasource = self
|
||||||
@ -48,11 +46,18 @@ import UIKit
|
|||||||
super.reset()
|
super.reset()
|
||||||
tabs.reset()
|
tabs.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
return 46
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TabsTableViewCell: TopTabbarDelegate {
|
extension TabsTableViewCell: TopTabbarDelegate {
|
||||||
public func shouldSelectItem(at index: Int, topTabbar: TopTabbar) -> Bool {
|
public func shouldSelectItem(at index: Int, topTabbar: TopTabbar) -> Bool {
|
||||||
if let molecules = tabsListItemModel?.molecules[topTabbar.selectedIndex] {
|
if let model = tabsListItemModel,
|
||||||
|
let json = model.toJSON(),
|
||||||
|
let json2d = json.optionalArrayForKey("molecules") as? [[[AnyHashable: Any]]] {
|
||||||
|
let molecules = json2d[topTabbar.selectedIndex]
|
||||||
delegateObject?.moleculeDelegate?.removeMolecules(molecules, sender: self, animation: index < tabs.selectedIndex ? .right : .left)
|
delegateObject?.moleculeDelegate?.removeMolecules(molecules, sender: self, animation: index < tabs.selectedIndex ? .right : .left)
|
||||||
}
|
}
|
||||||
previousTabIndex = tabs.selectedIndex
|
previousTabIndex = tabs.selectedIndex
|
||||||
@ -60,7 +65,10 @@ extension TabsTableViewCell: TopTabbarDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func topTabbar(_ topTabbar: TopTabbar, didSelectItemAt index: Int) {
|
public func topTabbar(_ topTabbar: TopTabbar, didSelectItemAt index: Int) {
|
||||||
if let molecules = tabsListItemModel?.molecules[index] {
|
if let model = tabsListItemModel,
|
||||||
|
let json = model.toJSON(),
|
||||||
|
let json2d = json.optionalArrayForKey("molecules") as? [[[AnyHashable: Any]]] {
|
||||||
|
let molecules = json2d[index]
|
||||||
delegateObject?.moleculeDelegate?.addMolecules(molecules, sender: self, animation: index < previousTabIndex ? .left : .right)
|
delegateObject?.moleculeDelegate?.addMolecules(molecules, sender: self, animation: index < previousTabIndex ? .left : .right)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,9 +24,8 @@ open class HeadlineBody: View {
|
|||||||
|
|
||||||
// MARK: - Styling
|
// MARK: - Styling
|
||||||
func style(with styleString: String?) {
|
func style(with styleString: String?) {
|
||||||
guard let styleString = styleString else {
|
guard let styleString = styleString else { return }
|
||||||
return
|
|
||||||
}
|
|
||||||
switch styleString {
|
switch styleString {
|
||||||
case "header":
|
case "header":
|
||||||
stylePageHeader()
|
stylePageHeader()
|
||||||
@ -72,10 +71,9 @@ open class HeadlineBody: View {
|
|||||||
|
|
||||||
open override func setupView() {
|
open override func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
guard subviews.count == 0 else {
|
|
||||||
return
|
guard subviews.isEmpty else { return }
|
||||||
}
|
|
||||||
translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
clipsToBounds = true
|
clipsToBounds = true
|
||||||
|
|
||||||
@ -86,9 +84,9 @@ open class HeadlineBody: View {
|
|||||||
view.addSubview(headlineLabel)
|
view.addSubview(headlineLabel)
|
||||||
view.addSubview(messageLabel)
|
view.addSubview(messageLabel)
|
||||||
|
|
||||||
headlineLabel.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical)
|
headlineLabel.setContentHuggingPriority(.required, for: .vertical)
|
||||||
messageLabel.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical)
|
messageLabel.setContentHuggingPriority(.required, for: .vertical)
|
||||||
view.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical)
|
view.setContentHuggingPriority(.required, for: .vertical)
|
||||||
|
|
||||||
headlineLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
|
headlineLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
|
||||||
|
|
||||||
@ -110,7 +108,10 @@ open class HeadlineBody: View {
|
|||||||
view.bottomAnchor.constraint(equalTo: messageLabel.bottomAnchor, constant: 0).isActive = true
|
view.bottomAnchor.constraint(equalTo: messageLabel.bottomAnchor, constant: 0).isActive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - Constraining
|
// MARK: - Constraining
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public func setSpacing() {
|
public func setSpacing() {
|
||||||
if headlineLabel.hasText && messageLabel.hasText {
|
if headlineLabel.hasText && messageLabel.hasText {
|
||||||
spaceBetweenLabels?.constant = spaceBetweenLabelsConstant
|
spaceBetweenLabels?.constant = spaceBetweenLabelsConstant
|
||||||
@ -119,25 +120,29 @@ open class HeadlineBody: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK:- ModelMoleculeViewProtocol
|
//--------------------------------------------------
|
||||||
|
// MARK: - ModelMoleculeViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
return 58
|
return 58
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
|
||||||
super.setWithModel(model, delegateObject, additionalData)
|
super.setWithModel(model, delegateObject, additionalData)
|
||||||
guard let headlineBodyModel = model as? HeadlineBodyModel else {
|
|
||||||
return
|
guard let headlineBodyModel = model as? HeadlineBodyModel else { return }
|
||||||
}
|
|
||||||
|
|
||||||
style(with: headlineBodyModel.style)
|
style(with: headlineBodyModel.style)
|
||||||
|
|
||||||
headlineLabel.setWithModel(headlineBodyModel.headline, delegateObject, additionalData)
|
headlineLabel.setWithModel(headlineBodyModel.headline, delegateObject, additionalData)
|
||||||
messageLabel.setWithModel(headlineBodyModel.body, delegateObject, additionalData)
|
messageLabel.setWithModel(headlineBodyModel.body, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, 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)
|
||||||
|
|
||||||
@ -159,4 +164,3 @@ open class HeadlineBody: View {
|
|||||||
return 58
|
return 58
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,4 +20,3 @@ import Foundation
|
|||||||
self.headline = headline
|
self.headline = headline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import Foundation
|
|||||||
public extension MVMCoreUIMoleculeMappingObject {
|
public extension MVMCoreUIMoleculeMappingObject {
|
||||||
|
|
||||||
func register<M: Model, V: MVMCoreUIMoleculeViewProtocol>(viewClass: V.Type, viewModelClass: M.Type) {
|
func register<M: Model, V: MVMCoreUIMoleculeViewProtocol>(viewClass: V.Type, viewModelClass: M.Type) {
|
||||||
ModelRegistry.register(viewModelClass)
|
try? ModelRegistry.register(viewModelClass)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(viewClass, forKey: viewModelClass.identifier as NSString)
|
MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(viewClass, forKey: viewModelClass.identifier as NSString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,8 +23,8 @@ public protocol MoleculeDelegateProtocol {
|
|||||||
func removeMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation)
|
func removeMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation)
|
||||||
|
|
||||||
//optional
|
//optional
|
||||||
func addMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation)
|
func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation)
|
||||||
func removeMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation)
|
func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation)
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MoleculeDelegateProtocol {
|
extension MoleculeDelegateProtocol {
|
||||||
@ -40,11 +40,11 @@ extension MoleculeDelegateProtocol {
|
|||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
public func addMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
public func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
public func removeMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
public func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,13 +18,13 @@ import Foundation
|
|||||||
|
|
||||||
// Label
|
// Label
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Label.self, viewModelClass: LabelModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Label.self, viewModelClass: LabelModel.self)
|
||||||
//need to move labelattributemodel to different method
|
// need to move labelattributemodel to different method
|
||||||
ModelRegistry.register(LabelAttributeFontModel.self)
|
try? ModelRegistry.register(LabelAttributeFontModel.self)
|
||||||
ModelRegistry.register(LabelAttributeColorModel.self)
|
try? ModelRegistry.register(LabelAttributeColorModel.self)
|
||||||
//ModelRegistry.register(LabelAttributeImageModel.self) // We need to separate the registry by types due to collisions...
|
try? ModelRegistry.register(LabelAttributeImageModel.self) // We need to separate the registry by types due to collisions...
|
||||||
ModelRegistry.register(LabelAttributeUnderlineModel.self)
|
try? ModelRegistry.register(LabelAttributeUnderlineModel.self)
|
||||||
ModelRegistry.register(LabelAttributeStrikeThroughModel.self)
|
try? ModelRegistry.register(LabelAttributeStrikeThroughModel.self)
|
||||||
ModelRegistry.register(LabelAttributeActionModel.self)
|
try? ModelRegistry.register(LabelAttributeActionModel.self)
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self)
|
||||||
@ -40,7 +40,6 @@ import Foundation
|
|||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: DateDropdownEntryField.self, viewModelClass: DateDropdownEntryFieldModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: DateDropdownEntryField.self, viewModelClass: DateDropdownEntryFieldModel.self)
|
||||||
|
|
||||||
// Other Atoms
|
// Other Atoms
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Label.self, viewModelClass: LabelModel.self)
|
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretView.self, viewModelClass: CaretViewModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretView.self, viewModelClass: CaretViewModel.self)
|
||||||
@ -55,6 +54,8 @@ import Foundation
|
|||||||
// Horizontal Combination Molecules
|
// Horizontal Combination Molecules
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self)
|
||||||
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListThreeColumnPlanDataDivider.self, viewModelClass: ListThreeColumnPlanDataDividerModel.self)
|
||||||
|
|
||||||
|
|
||||||
// Vertical Combination Molecules
|
// Vertical Combination Molecules
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self)
|
||||||
@ -70,9 +71,10 @@ import Foundation
|
|||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyToggle.self, viewModelClass: HeadlineBodyToggleModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyToggle.self, viewModelClass: HeadlineBodyToggleModel.self)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyLinkToggle.self, viewModelClass: HeadlineBodyLinkToggleModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyLinkToggle.self, viewModelClass: HeadlineBodyLinkToggleModel.self)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ActionDetailWithImage.self, viewModelClass: ActionDetailWithImageModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ActionDetailWithImage.self, viewModelClass: ActionDetailWithImageModel.self)
|
||||||
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListLeftVariableIconWithRightCaret.self, viewModelClass: ListLeftVariableIconWithRightCaretModel.self)
|
||||||
|
|
||||||
// List items
|
// List items
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeTableViewCell.self, viewModelClass: ListItemModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeTableViewCell.self, viewModelClass: MoleculeListItemModel.self)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: DropDownFilterTableViewCell.self, viewModelClass: DropDownListItemModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: DropDownFilterTableViewCell.self, viewModelClass: DropDownListItemModel.self)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: AccordionMoleculeTableViewCell.self, viewModelClass: AccordionListItemModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: AccordionMoleculeTableViewCell.self, viewModelClass: AccordionListItemModel.self)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TabsTableViewCell.self, viewModelClass: TabsListItemModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TabsTableViewCell.self, viewModelClass: TabsListItemModel.self)
|
||||||
@ -106,6 +108,6 @@ import Foundation
|
|||||||
MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(MVMCoreUIPageControl.self, forKey: "barsPager" as NSString)
|
MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(MVMCoreUIPageControl.self, forKey: "barsPager" as NSString)
|
||||||
|
|
||||||
// TODO: Need View
|
// TODO: Need View
|
||||||
ModelRegistry.register(TabsModel.self)
|
try? ModelRegistry.register(TabsModel.self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class ListPageTemplateModel: TemplateModelProtocol {
|
@objcMembers public class ListPageTemplateModel: TemplateModelProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public static var identifier: String = "list"
|
public static var identifier: String = "list"
|
||||||
|
|
||||||
public var pageType: String
|
public var pageType: String
|
||||||
@ -17,16 +20,24 @@ import Foundation
|
|||||||
public var isAtomicTabs: Bool?
|
public var isAtomicTabs: Bool?
|
||||||
|
|
||||||
public var header: MoleculeModelProtocol?
|
public var header: MoleculeModelProtocol?
|
||||||
public var molecules: [ListItemModelProtocol]?
|
public var molecules: [ListItemModelProtocol & MoleculeModelProtocol]?
|
||||||
public var footer: MoleculeModelProtocol?
|
public var footer: MoleculeModelProtocol?
|
||||||
public var line: LineModel?
|
public var line: LineModel?
|
||||||
|
|
||||||
public init(pageType: String, screenHeading: String?, molecules: [ListItemModelProtocol]) {
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializer
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public init(pageType: String, screenHeading: String?, molecules: [ListItemModelProtocol & MoleculeModelProtocol]) {
|
||||||
self.pageType = pageType
|
self.pageType = pageType
|
||||||
self.screenHeading = screenHeading
|
self.screenHeading = screenHeading
|
||||||
self.molecules = molecules
|
self.molecules = molecules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Keys
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case pageType
|
case pageType
|
||||||
@ -38,11 +49,15 @@ import Foundation
|
|||||||
case isAtomicTabs
|
case isAtomicTabs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codec
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
pageType = try typeContainer.decode(String.self, forKey: .pageType)
|
pageType = try typeContainer.decode(String.self, forKey: .pageType)
|
||||||
screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading)
|
screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading)
|
||||||
molecules = try typeContainer.decodeMoleculesIfPresent(codingKey: .molecules) as? [ListItemModelProtocol]
|
molecules = try typeContainer.decodeMoleculesIfPresent(codingKey: .molecules) as? [ListItemModelProtocol & MoleculeModelProtocol]
|
||||||
isAtomicTabs = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAtomicTabs)
|
isAtomicTabs = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAtomicTabs)
|
||||||
header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header)
|
header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header)
|
||||||
footer = try typeContainer.decodeMoleculeIfPresent(codingKey: .footer)
|
footer = try typeContainer.decodeMoleculeIfPresent(codingKey: .footer)
|
||||||
|
|||||||
@ -9,52 +9,67 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol {
|
open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Stored Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: (ListItemModelProtocol & MoleculeModelProtocol))]?
|
||||||
|
|
||||||
public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)]?
|
|
||||||
var observer: NSKeyValueObservation?
|
var observer: NSKeyValueObservation?
|
||||||
|
|
||||||
public var templateModel: ListPageTemplateModel?
|
public var templateModel: ListPageTemplateModel?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Computed Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
@objc public override func parsePageJSON() throws {
|
@objc public override func parsePageJSON() throws {
|
||||||
try parseTemplateJSON()
|
try parseTemplateJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override var loadObject: MVMCoreLoadObject? {
|
open override var loadObject: MVMCoreLoadObject? {
|
||||||
didSet {
|
didSet {
|
||||||
if loadObject != oldValue {
|
guard loadObject != oldValue else { return }
|
||||||
updateRequiredModules()
|
|
||||||
observer?.invalidate()
|
updateRequiredModules()
|
||||||
if let newObject = loadObject {
|
observer?.invalidate()
|
||||||
observer = newObject.observe(\MVMCoreLoadObject.pageJSON, options: [.old, .new]) { [weak self] (object, change) in
|
if let newObject = loadObject {
|
||||||
self?.updateRequiredModules()
|
observer = newObject.observe(\MVMCoreLoadObject.pageJSON, options: [.old, .new]) { [weak self] object, change in
|
||||||
}
|
self?.updateRequiredModules()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Methods
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func viewForTop() -> UIView {
|
open override func viewForTop() -> UIView {
|
||||||
guard let headerModel = templateModel?.header,
|
guard let headerModel = templateModel?.header,
|
||||||
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(headerModel, delegateObject() as? MVMCoreUIDelegateObject, false) else {
|
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(headerModel, delegateObject() as? MVMCoreUIDelegateObject, false)
|
||||||
return super.viewForTop()
|
else { return super.viewForTop() }
|
||||||
}
|
|
||||||
|
|
||||||
// Temporary, Default the horizontal padding
|
// Temporary, Default the horizontal padding
|
||||||
if var container = templateModel?.header as? ContainerModelProtocol, container.useHorizontalMargins == nil {
|
if var container = templateModel?.header as? ContainerModelProtocol, container.useHorizontalMargins == nil {
|
||||||
container.useHorizontalMargins = true
|
container.useHorizontalMargins = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return molecule
|
return molecule
|
||||||
}
|
}
|
||||||
|
|
||||||
override open func viewForBottom() -> UIView {
|
override open func viewForBottom() -> UIView {
|
||||||
guard let footerModel = templateModel?.footer,
|
guard let footerModel = templateModel?.footer,
|
||||||
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(footerModel, delegateObject() as? MVMCoreUIDelegateObject, false) else {
|
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(footerModel, delegateObject() as? MVMCoreUIDelegateObject, false)
|
||||||
return super.viewForBottom()
|
else { return super.viewForBottom() }
|
||||||
}
|
|
||||||
return molecule
|
return molecule
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
|
open override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
|
||||||
|
|
||||||
guard super.shouldFinishProcessingLoad(loadObject, error: error) else { return false }
|
guard super.shouldFinishProcessingLoad(loadObject, error: error) else { return false }
|
||||||
|
|
||||||
// This template requires atleast one of the three layers.
|
// This template requires atleast one of the three layers.
|
||||||
if templateModel?.header == nil,
|
if templateModel?.header == nil,
|
||||||
templateModel?.molecules?.count ?? 0 == 0,
|
templateModel?.molecules?.count ?? 0 == 0,
|
||||||
@ -72,7 +87,10 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
registerWithTable()
|
registerWithTable()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - table
|
//--------------------------------------------------
|
||||||
|
// MARK: - Table View
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func registerWithTable() {
|
open override func registerWithTable() {
|
||||||
super.registerWithTable()
|
super.registerWithTable()
|
||||||
guard let moleculesInfo = moleculesInfo else { return }
|
guard let moleculesInfo = moleculesInfo else { return }
|
||||||
@ -84,9 +102,9 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
|
|
||||||
open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
|
open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
|
||||||
guard let moleculeInfo = moleculesInfo?[indexPath.row],
|
guard let moleculeInfo = moleculesInfo?[indexPath.row],
|
||||||
let estimatedHeight = (moleculeInfo.class as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(forRow: moleculeInfo.molecule, delegateObject: delegateObject() as? MVMCoreUIDelegateObject) else {
|
let estimatedHeight = (moleculeInfo.class as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(forRow: moleculeInfo.molecule, delegateObject: delegateObject() as? MVMCoreUIDelegateObject)
|
||||||
return 0
|
else { return 0 }
|
||||||
}
|
|
||||||
return estimatedHeight
|
return estimatedHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,18 +113,22 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
|
|
||||||
guard let moleculeInfo = moleculesInfo?[indexPath.row],
|
guard let moleculeInfo = moleculesInfo?[indexPath.row],
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier) else {
|
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier)
|
||||||
return UITableViewCell()
|
else { return UITableViewCell() }
|
||||||
}
|
|
||||||
let delegate = delegateObject() as? MVMCoreUIDelegateObject
|
let delegate = delegateObject() as? MVMCoreUIDelegateObject
|
||||||
let moleculeCell = cell as? MVMCoreUIMoleculeViewProtocol
|
let moleculeCell = cell as? MVMCoreUIMoleculeViewProtocol
|
||||||
moleculeCell?.reset?()
|
moleculeCell?.reset?()
|
||||||
|
|
||||||
if let protocolCell = cell as? MoleculeListCellProtocol {
|
if let protocolCell = cell as? MoleculeListCellProtocol {
|
||||||
protocolCell.setLines(with: templateModel?.line, delegateObject: delegate, additionalData: nil, indexPath: indexPath)
|
protocolCell.setLines(with: templateModel?.line, delegateObject: delegate, additionalData: nil, indexPath: indexPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
(moleculeCell as? ModelMoleculeViewProtocol)?.setWithModel(moleculeInfo.molecule, delegate, nil)
|
(moleculeCell as? ModelMoleculeViewProtocol)?.setWithModel(moleculeInfo.molecule, delegate, nil)
|
||||||
moleculeCell?.updateView(tableView.bounds.width)
|
moleculeCell?.updateView(tableView.bounds.width)
|
||||||
|
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,16 +140,18 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
|
||||||
if let cell = tableView.cellForRow(at: indexPath) as? MoleculeListCellProtocol {
|
if let cell = tableView.cellForRow(at: indexPath) as? MoleculeListCellProtocol {
|
||||||
cell.didSelectCell(at: indexPath, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
|
cell.didSelectCell(at: indexPath, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - cache handling
|
//--------------------------------------------------
|
||||||
|
// MARK: - Cache Handling
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func pageTypesToListenFor() -> [Any]? {
|
open override func pageTypesToListenFor() -> [Any]? {
|
||||||
guard let pageType = self.pageType else {
|
guard let pageType = self.pageType else { return super.pageTypesToListenFor() }
|
||||||
return super.pageTypesToListenFor()
|
|
||||||
}
|
|
||||||
return [pageType]
|
return [pageType]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,8 +159,12 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
return loadObject?.requestParameters?.modules
|
return loadObject?.requestParameters?.modules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - MoleculeDelegateProtocol
|
// MARK: - MoleculeDelegateProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) {
|
open override func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) {
|
||||||
|
|
||||||
if let tableView = tableView {
|
if let tableView = tableView {
|
||||||
let point = molecule.convert(molecule.bounds.origin, to: tableView)
|
let point = molecule.convert(molecule.bounds.origin, to: tableView)
|
||||||
if let indexPath = tableView.indexPathForRow(at: point), tableView.indexPathsForVisibleRows?.contains(indexPath) ?? false {
|
if let indexPath = tableView.indexPathForRow(at: point), tableView.indexPathsForVisibleRows?.contains(indexPath) ?? false {
|
||||||
@ -148,10 +176,10 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
|
|
||||||
public override func addMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
public override func addMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||||
|
|
||||||
var tmpMolecules = [ListItemModelProtocol]()
|
var tmpMolecules = [ListItemModelProtocol & MoleculeModelProtocol]()
|
||||||
|
|
||||||
molecules.forEach { molecule in
|
molecules.forEach { molecule in
|
||||||
if let data = try? JSONSerialization.data(withJSONObject: molecule), let listItemModel = try? JSONDecoder().decode(ListItemModel.self, from: data) {
|
if let data = try? JSONSerialization.data(withJSONObject: molecule), let listItemModel = try? JSONDecoder().decode(MoleculeListItemModel.self, from: data) {
|
||||||
tmpMolecules.append(listItemModel)
|
tmpMolecules.append(listItemModel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,6 +187,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
guard let indexPath = self.tableView?.indexPath(for: sender) else { return }
|
guard let indexPath = self.tableView?.indexPath(for: sender) else { return }
|
||||||
var indexPaths: [IndexPath] = []
|
var indexPaths: [IndexPath] = []
|
||||||
|
|
||||||
for molecule in tmpMolecules {
|
for molecule in tmpMolecules {
|
||||||
if let info = self.getMoleculeInfo(with: molecule) {
|
if let info = self.getMoleculeInfo(with: molecule) {
|
||||||
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
|
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
|
||||||
@ -167,6 +196,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
indexPaths.append(IndexPath(row: index, section: 0))
|
indexPaths.append(IndexPath(row: index, section: 0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tableView?.insertRows(at: indexPaths, with: animation)
|
self.tableView?.insertRows(at: indexPaths, with: animation)
|
||||||
self.updateViewConstraints()
|
self.updateViewConstraints()
|
||||||
self.view.layoutIfNeeded()
|
self.view.layoutIfNeeded()
|
||||||
@ -175,34 +205,39 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
|
|
||||||
public override func removeMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
public override func removeMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||||
|
|
||||||
var tmpMolecules = [ListItemModelProtocol]()
|
var tmpMolecules = [ListItemModelProtocol & MoleculeModelProtocol]()
|
||||||
|
|
||||||
molecules.forEach { molecule in
|
molecules.forEach { molecule in
|
||||||
if let data = try? JSONSerialization.data(withJSONObject: molecule), let listItemModel = try? JSONDecoder().decode(ListItemModel.self, from: data) {
|
if let data = try? JSONSerialization.data(withJSONObject: molecule),
|
||||||
|
let listItemModel = try? JSONDecoder().decode(MoleculeListItemModel.self, from: data) {
|
||||||
tmpMolecules.append(listItemModel)
|
tmpMolecules.append(listItemModel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var indexPaths: [IndexPath] = []
|
var indexPaths: [IndexPath] = []
|
||||||
|
|
||||||
//TODO: cehck for molecule protocola eqality
|
//TODO: cehck for molecule protocola eqality
|
||||||
|
|
||||||
for molecule in tmpMolecules {
|
for molecule in tmpMolecules {
|
||||||
if let removeIndex = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in
|
if let removeIndex = moleculesInfo?.firstIndex(where: { molecule.toJSON() == $0.molecule.toJSON() }) {
|
||||||
return molecule.toJSONString() == moleculeInfo.molecule.toJSONString()
|
|
||||||
}) {
|
|
||||||
moleculesInfo?.remove(at: removeIndex)
|
moleculesInfo?.remove(at: removeIndex)
|
||||||
indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0))
|
indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.tableView?.deleteRows(at: indexPaths, with: animation)
|
|
||||||
self.updateViewConstraints()
|
tableView?.deleteRows(at: indexPaths, with: animation)
|
||||||
self.view.layoutIfNeeded()
|
updateViewConstraints()
|
||||||
|
view.layoutIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func addMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
public func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||||
|
|
||||||
// This dispatch is needed to fix a race condition that can occur if this function is called during the table setup.
|
// This dispatch is needed to fix a race condition that can occur if this function is called during the table setup.
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
guard let indexPath = self.tableView?.indexPath(for: sender) else { return }
|
guard let indexPath = self.tableView?.indexPath(for: sender) else { return }
|
||||||
var indexPaths: [IndexPath] = []
|
var indexPaths: [IndexPath] = []
|
||||||
|
|
||||||
for molecule in molecules {
|
for molecule in molecules {
|
||||||
if let info = self.getMoleculeInfo(with: molecule) {
|
if let info = self.getMoleculeInfo(with: molecule) {
|
||||||
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
|
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
|
||||||
@ -211,42 +246,50 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
indexPaths.append(IndexPath(row: index, section: 0))
|
indexPaths.append(IndexPath(row: index, section: 0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tableView?.insertRows(at: indexPaths, with: animation)
|
self.tableView?.insertRows(at: indexPaths, with: animation)
|
||||||
self.updateViewConstraints()
|
self.updateViewConstraints()
|
||||||
self.view.layoutIfNeeded()
|
self.view.layoutIfNeeded()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func removeMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
public func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||||
|
|
||||||
var indexPaths: [IndexPath] = []
|
var indexPaths: [IndexPath] = []
|
||||||
//TODO: cehck for molecule protocola eqality
|
//TODO: cehck for molecule protocola eqality
|
||||||
|
|
||||||
for molecule in molecules {
|
for molecule in molecules {
|
||||||
if let removeIndex = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in
|
if let removeIndex = moleculesInfo?.firstIndex(where: { molecule.toJSON() == $0.molecule.toJSON() }) {
|
||||||
return molecule.toJSONString() == moleculeInfo.molecule.toJSONString()
|
|
||||||
}) {
|
|
||||||
moleculesInfo?.remove(at: removeIndex)
|
moleculesInfo?.remove(at: removeIndex)
|
||||||
indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0))
|
indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.tableView?.deleteRows(at: indexPaths, with: animation)
|
|
||||||
self.updateViewConstraints()
|
tableView?.deleteRows(at: indexPaths, with: animation)
|
||||||
self.view.layoutIfNeeded()
|
updateViewConstraints()
|
||||||
|
view.layoutIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - Convenience
|
// MARK: - Convenience
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
/// Returns the (identifier, class) of the molecule for the given map.
|
/// Returns the (identifier, class) of the molecule for the given map.
|
||||||
func getMoleculeInfo(with listItem: ListItemModelProtocol?) -> (identifier: String, class: AnyClass, molecule: ListItemModelProtocol)? {
|
func getMoleculeInfo(with listItem: (ListItemModelProtocol & MoleculeModelProtocol)?) -> (identifier: String, class: AnyClass, molecule: ListItemModelProtocol & MoleculeModelProtocol)? {
|
||||||
|
|
||||||
guard let listItem = listItem,
|
guard let listItem = listItem,
|
||||||
let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(listItem),
|
let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(listItem),
|
||||||
let moleculeName = (moleculeClass as? ModelMoleculeViewProtocol.Type)?.nameForReuse(listItem, delegateObject() as? MVMCoreUIDelegateObject) ?? listItem.moleculeName else {
|
let moleculeName = (moleculeClass as? ModelMoleculeViewProtocol.Type)?.nameForReuse(listItem, delegateObject() as? MVMCoreUIDelegateObject) ?? listItem.moleculeName
|
||||||
return nil
|
else { return nil }
|
||||||
}
|
|
||||||
return (moleculeName, moleculeClass, listItem)
|
return (moleculeName, moleculeClass, listItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets up the molecule list and ensures no errors loading all content.
|
/// Sets up the molecule list and ensures no errors loading all content.
|
||||||
func getMoleculeInfoList() -> [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)]? {
|
func getMoleculeInfoList() -> [(identifier: String, class: AnyClass, molecule: (ListItemModelProtocol & MoleculeModelProtocol))]? {
|
||||||
var moleculeList: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)] = []
|
|
||||||
|
var moleculeList: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol & MoleculeModelProtocol)] = []
|
||||||
|
|
||||||
if let molecules = templateModel?.molecules {
|
if let molecules = templateModel?.molecules {
|
||||||
for molecule in molecules {
|
for molecule in molecules {
|
||||||
if let info = getMoleculeInfo(with: molecule) {
|
if let info = getMoleculeInfo(with: molecule) {
|
||||||
@ -254,6 +297,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return moleculeList.count > 0 ? moleculeList : nil
|
return moleculeList.count > 0 ? moleculeList : nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,15 +315,19 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
|
|
||||||
/// Gets modules required by the loadObject.pageJSON.
|
/// Gets modules required by the loadObject.pageJSON.
|
||||||
open func requiredModules() -> [Any]? {
|
open func requiredModules() -> [Any]? {
|
||||||
|
|
||||||
let modules: NSMutableArray = []
|
let modules: NSMutableArray = []
|
||||||
let delegate = delegateObject() as? MVMCoreUIDelegateObject
|
let delegate = delegateObject() as? MVMCoreUIDelegateObject
|
||||||
|
|
||||||
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate, moduleList: modules, errorList: nil)
|
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate, moduleList: modules, errorList: nil)
|
||||||
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate, moduleList: modules, errorList: nil)
|
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate, moduleList: modules, errorList: nil)
|
||||||
|
|
||||||
if let molecules = loadObject?.pageJSON?.optionalArrayForKey(KeyMolecules) as? [[AnyHashable: Any]] {
|
if let molecules = loadObject?.pageJSON?.optionalArrayForKey(KeyMolecules) as? [[AnyHashable: Any]] {
|
||||||
for molecule in molecules {
|
for molecule in molecules {
|
||||||
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: molecule, delegateObject: delegate, moduleList: modules, errorList: nil)
|
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: molecule, delegateObject: delegate, moduleList: modules, errorList: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return modules as? [Any]
|
return modules as? [Any]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ public protocol TemplateProtocol: class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public extension TemplateProtocol where Self: MFViewController {
|
public extension TemplateProtocol where Self: MFViewController {
|
||||||
|
|
||||||
func parseTemplateJSON() throws {
|
func parseTemplateJSON() throws {
|
||||||
guard let pageJSON = self.loadObject?.pageJSON else { return }
|
guard let pageJSON = self.loadObject?.pageJSON else { return }
|
||||||
let data = try JSONSerialization.data(withJSONObject: pageJSON)
|
let data = try JSONSerialization.data(withJSONObject: pageJSON)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user