Merge branch 'develop' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui into feature/circular_progress_bar
This commit is contained in:
commit
f8fea032b5
@ -27,6 +27,7 @@
|
||||
012A88F123985E0100FE3DA1 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88F023985E0100FE3DA1 /* Color.swift */; };
|
||||
012CA99A2384A687003F810F /* MFTextField+ModelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012CA9992384A687003F810F /* MFTextField+ModelExtension.swift */; };
|
||||
012CA99E2385A2D3003F810F /* MFView+ModelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012CA99D2385A2D3003F810F /* MFView+ModelExtension.swift */; };
|
||||
013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */; };
|
||||
014AA72423C501E2006F3E93 /* MoleculeContainerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */; };
|
||||
014AA72523C501E2006F3E93 /* ContainerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014AA72223C501E2006F3E93 /* ContainerModel.swift */; };
|
||||
014AA72623C501E2006F3E93 /* ContainerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014AA72323C501E2006F3E93 /* ContainerModelProtocol.swift */; };
|
||||
@ -54,7 +55,7 @@
|
||||
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 */; };
|
||||
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 */; };
|
||||
01EB369323609801006832FA /* HeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368C23609801006832FA /* HeaderModel.swift */; };
|
||||
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368D23609801006832FA /* HeadlineBodyModel.swift */; };
|
||||
@ -95,6 +96,10 @@
|
||||
0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; };
|
||||
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.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 */; };
|
||||
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; };
|
||||
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; };
|
||||
@ -167,6 +172,7 @@
|
||||
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 */; };
|
||||
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 */; };
|
||||
D2755D7B23689C7500485468 /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2755D7A23689C7500485468 /* TableViewCell.swift */; };
|
||||
D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */; };
|
||||
@ -309,6 +315,7 @@
|
||||
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, ); }; };
|
||||
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 */; };
|
||||
D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */; };
|
||||
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */; };
|
||||
@ -329,7 +336,7 @@
|
||||
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */; };
|
||||
DBC4391822442197001AB423 /* CaretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391622442196001AB423 /* CaretView.swift */; };
|
||||
DBC4391922442197001AB423 /* DashLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391722442197001AB423 /* DashLine.swift */; };
|
||||
DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretButton.swift */; };
|
||||
DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretLink.swift */; };
|
||||
DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */; };
|
||||
DBEFFA04225A829700230692 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB891E822253FA8500022516 /* Label.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
@ -355,6 +362,7 @@
|
||||
012A88F023985E0100FE3DA1 /* Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = "<group>"; };
|
||||
012CA9992384A687003F810F /* MFTextField+ModelExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFTextField+ModelExtension.swift"; sourceTree = "<group>"; };
|
||||
012CA99D2385A2D3003F810F /* MFView+ModelExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFView+ModelExtension.swift"; sourceTree = "<group>"; };
|
||||
013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIContentMode+Extension.swift"; sourceTree = "<group>"; };
|
||||
014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeContainerModel.swift; sourceTree = "<group>"; };
|
||||
014AA72223C501E2006F3E93 /* ContainerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContainerModel.swift; sourceTree = "<group>"; };
|
||||
014AA72323C501E2006F3E93 /* ContainerModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContainerModelProtocol.swift; sourceTree = "<group>"; };
|
||||
@ -381,7 +389,7 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -414,6 +422,10 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -484,6 +496,7 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -641,6 +654,7 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -655,14 +669,13 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
DB891E822253FA8500022516 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = "<group>"; };
|
||||
DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = "<group>"; };
|
||||
DBC4391722442197001AB423 /* DashLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashLine.swift; sourceTree = "<group>"; };
|
||||
DBC4391A224421A0001AB423 /* CaretButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretButton.swift; sourceTree = "<group>"; };
|
||||
DBC4391A224421A0001AB423 /* CaretLink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretLink.swift; sourceTree = "<group>"; };
|
||||
DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelWithInternalButton.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@ -839,6 +852,8 @@
|
||||
D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */,
|
||||
D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */,
|
||||
D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */,
|
||||
94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */,
|
||||
94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */,
|
||||
D282AACA2243C61700C46919 /* ButtonView.swift */,
|
||||
94AF4A3C23E9D13900676048 /* MFCaretButton.h */,
|
||||
94AF4A3D23E9D13900676048 /* MFCaretButton.m */,
|
||||
@ -889,8 +904,6 @@
|
||||
D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */,
|
||||
D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */,
|
||||
D28A837E23CCA96400DFE4FC /* TabsModel.swift */,
|
||||
94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */,
|
||||
94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */,
|
||||
);
|
||||
path = HorizontalCombinationViews;
|
||||
sourceTree = "<group>";
|
||||
@ -924,8 +937,8 @@
|
||||
D22479912316A9EF003FCCF9 /* Items */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D2755D7A23689C7500485468 /* TableViewCell.swift */,
|
||||
01EB368923609801006832FA /* ListItemModel.swift */,
|
||||
D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */,
|
||||
01EB368923609801006832FA /* MoleculeListItemModel.swift */,
|
||||
01509D8E2327EC6F00EF99AA /* MoleculeTableViewCell.swift */,
|
||||
012A88C1238D7BCA00FE3DA1 /* CarouselItemModel.swift */,
|
||||
D2A6390422CBCE160052ED1F /* MoleculeCollectionViewCell.swift */,
|
||||
@ -944,6 +957,49 @@
|
||||
path = Items;
|
||||
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 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1046,6 +1102,7 @@
|
||||
D29DF10E21E67A77003B2FB9 /* Molecules */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D22B38E923F4E07800490EF6 /* DesignedComponents */,
|
||||
D22479912316A9EF003FCCF9 /* Items */,
|
||||
D224798F2316A99F003FCCF9 /* LeftRightViews */,
|
||||
D224798E2316A995003FCCF9 /* HorizontalCombinationViews */,
|
||||
@ -1085,7 +1142,7 @@
|
||||
D29DF2CD21E7C104003B2FB9 /* MFLoadingViewController.m */,
|
||||
D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */,
|
||||
D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */,
|
||||
D2F4DDE52371A4CB00CD28BB /* ViewController.swift */,
|
||||
D2C521A823EDE79E00CA2634 /* ViewController.swift */,
|
||||
);
|
||||
path = BaseControllers;
|
||||
sourceTree = "<group>";
|
||||
@ -1093,6 +1150,7 @@
|
||||
D29DF11021E6805F003B2FB9 /* Categories */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */,
|
||||
D29DF11121E6805F003B2FB9 /* UIColor+MFConvenience.h */,
|
||||
D29DF11321E6805F003B2FB9 /* UIColor+MFConvenience.m */,
|
||||
D29DF11221E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.h */,
|
||||
@ -1174,7 +1232,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
01F2A03123A4498200D954D8 /* CaretLinkModel.swift */,
|
||||
DBC4391A224421A0001AB423 /* CaretButton.swift */,
|
||||
DBC4391A224421A0001AB423 /* CaretLink.swift */,
|
||||
D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */,
|
||||
D2E2A99E23E07F8A000B42E6 /* PillButton.swift */,
|
||||
D28A838823CCCFCB00DFE4FC /* LinkModel.swift */,
|
||||
@ -1383,6 +1441,7 @@
|
||||
D2B18B7E2360913400A9AEDC /* Control.swift */,
|
||||
D2B18B802360945C00A9AEDC /* View.swift */,
|
||||
0AE14F63238315D2005417F8 /* TextField.swift */,
|
||||
D2755D7A23689C7500485468 /* TableViewCell.swift */,
|
||||
0A5D59C323AD488600EFD9E9 /* Protocols */,
|
||||
);
|
||||
path = BaseClasses;
|
||||
@ -1547,6 +1606,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */,
|
||||
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
|
||||
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */,
|
||||
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */,
|
||||
@ -1635,7 +1695,7 @@
|
||||
012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */,
|
||||
D2A514672213885800345BFB /* HeaderView.swift in Sources */,
|
||||
D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */,
|
||||
01EB369023609801006832FA /* ListItemModel.swift in Sources */,
|
||||
01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */,
|
||||
D28A838323CCBD3F00DFE4FC /* CircleProgressModel.swift in Sources */,
|
||||
D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */,
|
||||
DBEFFA04225A829700230692 /* Label.swift in Sources */,
|
||||
@ -1645,6 +1705,7 @@
|
||||
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */,
|
||||
D260105523CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift in Sources */,
|
||||
D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */,
|
||||
5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */,
|
||||
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */,
|
||||
0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */,
|
||||
94F217B723E0BF6100A47C06 /* PrimaryButtonView.m in Sources */,
|
||||
@ -1695,6 +1756,7 @@
|
||||
94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */,
|
||||
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
|
||||
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */,
|
||||
8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */,
|
||||
D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */,
|
||||
012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */,
|
||||
D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */,
|
||||
@ -1708,6 +1770,7 @@
|
||||
D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */,
|
||||
D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */,
|
||||
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */,
|
||||
8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */,
|
||||
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
|
||||
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */,
|
||||
0A21DB89235E06EF00C160A2 /* MFMdnTextField.m in Sources */,
|
||||
@ -1727,6 +1790,7 @@
|
||||
D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */,
|
||||
0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */,
|
||||
D243859923A16B1800332775 /* Container.swift in Sources */,
|
||||
D2C521A923EDE79E00CA2634 /* ViewController.swift in Sources */,
|
||||
D260105B23D0BB7100764D80 /* StackModelProtocol.swift in Sources */,
|
||||
D29DF29821E7ADB8003B2FB9 /* MFScrollingViewController.m in Sources */,
|
||||
D28A839323CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift in Sources */,
|
||||
@ -1742,11 +1806,13 @@
|
||||
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */,
|
||||
D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */,
|
||||
0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */,
|
||||
D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */,
|
||||
0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */,
|
||||
94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */,
|
||||
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */,
|
||||
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
|
||||
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */,
|
||||
013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */,
|
||||
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */,
|
||||
D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */,
|
||||
D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */,
|
||||
@ -1758,7 +1824,7 @@
|
||||
012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */,
|
||||
D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */,
|
||||
C003506123AA94CD00B6AC29 /* Button.swift in Sources */,
|
||||
DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */,
|
||||
DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */,
|
||||
0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */,
|
||||
0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */,
|
||||
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */,
|
||||
|
||||
@ -20,7 +20,6 @@ public enum ButtonSize: String, Codable {
|
||||
|
||||
public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
|
||||
public static var identifier: String = "button"
|
||||
public var moleculeName: String?
|
||||
public var backgroundColor: Color?
|
||||
public var title: String
|
||||
public var action: ActionModelProtocol
|
||||
@ -41,6 +40,18 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
|
||||
self.action = action
|
||||
}
|
||||
|
||||
init(secondaryButtonWith title: String, action: ActionModelProtocol) {
|
||||
self.title = title
|
||||
self.action = action
|
||||
style = .secondary
|
||||
}
|
||||
|
||||
init(primaryButtonWith title: String, action: ActionModelProtocol) {
|
||||
self.title = title
|
||||
self.action = action
|
||||
style = .primary
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
@ -61,7 +72,6 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName)
|
||||
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
title = try typeContainer.decode(String.self, forKey: .title)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// CaretButton.swift
|
||||
// CaretLink.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Kolli, Praneeth on 1/5/18.
|
||||
@ -8,7 +8,7 @@
|
||||
//
|
||||
|
||||
|
||||
open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol, ModelMoleculeViewProtocol {
|
||||
open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol {
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Constants
|
||||
@ -49,7 +49,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI
|
||||
didSet { changeCaretColor() }
|
||||
}
|
||||
|
||||
public func updateView(_ size: CGFloat) {
|
||||
public override func updateView(_ size: CGFloat) {
|
||||
titleLabel?.font = MFStyler.fontB1()
|
||||
}
|
||||
|
||||
@ -125,33 +125,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI
|
||||
setTitleColor(disabledColor, for: .disabled)
|
||||
}
|
||||
|
||||
@objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
setWithActionMap(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
|
||||
guard let dictionary = json else { return }
|
||||
|
||||
if let title = dictionary.optionalStringForKey(KeyTitle) {
|
||||
setTitle(title, for: .normal)
|
||||
}
|
||||
|
||||
if let disableButtonAsAny = dictionary[KeyDisableButton], let isDisabled = disableButtonAsAny as? Bool {
|
||||
isEnabled = !isDisabled
|
||||
}
|
||||
|
||||
if let backgroundColorHex = dictionary[KeyBackgroundColor] as? String {
|
||||
backgroundColor = UIColor.mfGet(forHex: backgroundColorHex)
|
||||
}
|
||||
|
||||
if let enabledColorHex = dictionary["enabledColor"] as? String {
|
||||
enabledColor = UIColor.mfGet(forHex: enabledColorHex)
|
||||
}
|
||||
|
||||
if let disabledColorHex = dictionary["disabledColor"] as? String {
|
||||
disabledColor = UIColor.mfGet(forHex: disabledColorHex)
|
||||
}
|
||||
}
|
||||
|
||||
public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
guard let caretLinkModel = model as? CaretLinkModel else { return }
|
||||
if let color = caretLinkModel.backgroundColor {
|
||||
backgroundColor = color.uiColor
|
||||
@ -173,7 +147,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI
|
||||
return .leading
|
||||
}
|
||||
|
||||
public class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
return 10
|
||||
open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 10.5
|
||||
}
|
||||
}
|
||||
@ -97,9 +97,9 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation
|
||||
public static func getHeight(for buttonSize: ButtonSize?, size: CGFloat) -> CGFloat {
|
||||
switch buttonSize {
|
||||
case .tiny:
|
||||
return MFSizeObject(standardSize: ButtonHeight.tiny.rawValue, standardiPadPortraitSize: 34, iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? 20
|
||||
return MFSizeObject(standardSize: ButtonHeight.tiny.rawValue, standardiPadPortraitSize: 34, iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? ButtonHeight.tiny.rawValue
|
||||
default:
|
||||
return MFSizeObject(standardSize: ButtonHeight.standard.rawValue, standardiPadPortraitSize: 46, iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? 42
|
||||
return MFSizeObject(standardSize: ButtonHeight.standard.rawValue, standardiPadPortraitSize: 46, iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? ButtonHeight.standard.rawValue
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation
|
||||
case .tiny:
|
||||
return MFSizeObject(standardSize: 49.0, standardiPadPortraitSize: 90.0, iPadProLandscapeSize: 135.0)?.getValueBased(onSize: size) ?? 49.0
|
||||
default:
|
||||
return MFSizeObject(standardSize: 102.0, standardiPadPortraitSize: 136.0, iPadProLandscapeSize: 153.0)?.getValueBased(onSize: size) ?? 102.0
|
||||
return 151.0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ import UIKit
|
||||
let caret = CaretView()
|
||||
caret.direction = .down
|
||||
caret.lineWidth = 1.5
|
||||
caret.isUserInteractionEnabled = true
|
||||
caret.isUserInteractionEnabled = false
|
||||
caret.heightAnchor.constraint(equalToConstant: 9).isActive = true
|
||||
caret.widthAnchor.constraint(equalToConstant: 16).isActive = true
|
||||
return caret
|
||||
|
||||
@ -37,7 +37,7 @@ import Foundation
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case title
|
||||
case title = "label"
|
||||
case isEnabled
|
||||
case feedback
|
||||
case errorMessage = "errorMsg"
|
||||
|
||||
@ -26,6 +26,10 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
||||
/// Closure passed here will run upon dismissing the selection picker.
|
||||
public var observeDropdownSelection: ((String)->())?
|
||||
|
||||
public var itemDropdownEntryFieldModel: ItemDropdownEntryFieldModel? {
|
||||
return model as? ItemDropdownEntryFieldModel
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
@ -100,7 +104,7 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
||||
setPickerDelegates(delegate: self)
|
||||
|
||||
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])
|
||||
text = pickerData[row]
|
||||
itemDropdownEntryFieldModel?.selectedIndex = row
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
}
|
||||
|
||||
public var options: [String] = []
|
||||
public var selectedIndex: Int = 0
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
@ -24,6 +25,7 @@
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case options
|
||||
case selectedIndex
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -34,6 +36,7 @@
|
||||
try super.init(from: decoder)
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
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 {
|
||||
@ -41,5 +44,6 @@
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(options, forKey: .options)
|
||||
try container.encode(options, forKey: .selectedIndex)
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
import UIKit
|
||||
|
||||
|
||||
@objc public protocol ObservingTextFieldDelegate: NSObjectProtocol {
|
||||
@objc public protocol ObservingTextFieldDelegate {
|
||||
/// Called when the entered text becomes valid based on the validation block
|
||||
@objc optional func isValid(textfield: TextEntryField?)
|
||||
/// Called when the entered text becomes invalid based on the validation block
|
||||
@ -25,7 +25,7 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
|
||||
open private(set) var textField: TextField = {
|
||||
let textField = TextField(frame: .zero)
|
||||
let textField = TextField()
|
||||
textField.isAccessibilityElement = true
|
||||
textField.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
textField.font = MFStyler.fontForTextField()
|
||||
@ -58,7 +58,7 @@ import UIKit
|
||||
get { return super.isEnabled }
|
||||
set (enabled) {
|
||||
super.isEnabled = enabled
|
||||
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
@ -85,7 +85,10 @@ import UIKit
|
||||
/// The text of this TextField.
|
||||
open override var text: String? {
|
||||
get { return textField.text }
|
||||
set { textField.text = newValue }
|
||||
set {
|
||||
textField.text = newValue
|
||||
(model as? TextEntryFieldModel)?.text = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/// Placeholder access for the TextField.
|
||||
@ -99,7 +102,7 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
|
||||
public var validationBlock: ((_ value: String?) -> Bool)?
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Delegate Properties
|
||||
//--------------------------------------------------
|
||||
@ -169,6 +172,9 @@ import UIKit
|
||||
textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 16)
|
||||
textFieldTrailingConstraint?.isActive = true
|
||||
|
||||
textField.addTarget(self, action: #selector(startEditing), for: .editingDidBegin)
|
||||
textField.addTarget(self, action: #selector(dismissFieldInput(_:)), for: .editingDidEnd)
|
||||
|
||||
let tap = UITapGestureRecognizer(target: self, action: #selector(startEditing))
|
||||
entryFieldContainer.addGestureRecognizer(tap)
|
||||
|
||||
@ -225,7 +231,7 @@ import UIKit
|
||||
/// Validates the text of the entry field.
|
||||
@discardableResult
|
||||
@objc public func validateTextField() -> Bool {
|
||||
|
||||
|
||||
isValid = validationBlock?(text) ?? true
|
||||
|
||||
if isValid {
|
||||
@ -277,7 +283,7 @@ import UIKit
|
||||
guard let model = model as? TextEntryFieldModel else { return }
|
||||
|
||||
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
|
||||
|
||||
|
||||
textColor.enabled = model.enabledTextColor?.uiColor
|
||||
textColor.disabled = model.disabledTextColor?.uiColor
|
||||
text = model.text
|
||||
|
||||
@ -17,6 +17,7 @@ public enum GraphStyle: String, Codable {
|
||||
}
|
||||
|
||||
public class CircleProgressModel: MoleculeModelProtocol {
|
||||
|
||||
public static var identifier: String = "circleProgress"
|
||||
public var style: GraphStyle = .unlimited {
|
||||
didSet {
|
||||
|
||||
@ -11,11 +11,15 @@ import Foundation
|
||||
@objcMembers public class ImageViewModel: MoleculeModelProtocol {
|
||||
public static var identifier: String = "image"
|
||||
public var backgroundColor: Color?
|
||||
|
||||
public var image: String
|
||||
public var accessibilityText: String?
|
||||
public var fallbackImage: String?
|
||||
public var imageFormat: String?
|
||||
public var width: CGFloat?
|
||||
public var height: CGFloat?
|
||||
public var contentMode: UIView.ContentMode?
|
||||
|
||||
public init(image: String) {
|
||||
self.image = image
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,17 +220,27 @@ public typealias ActionBlock = () -> ()
|
||||
}
|
||||
|
||||
public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
clauses = []
|
||||
guard let labelModel = model as? LabelModel else { return }
|
||||
|
||||
guard let labelModel = model as? LabelModel else {
|
||||
text = ""
|
||||
return
|
||||
}
|
||||
|
||||
attributedText = nil
|
||||
originalAttributedString = nil
|
||||
text = labelModel.text
|
||||
Label.setLabel(self, withHTML: labelModel.html)
|
||||
|
||||
let alignment = LabelAlignment(rawValue: labelModel.textAlignment ?? "")
|
||||
switch alignment {
|
||||
case .center:
|
||||
textAlignment = .center
|
||||
|
||||
case .right:
|
||||
textAlignment = .right
|
||||
|
||||
default:
|
||||
textAlignment = .left
|
||||
}
|
||||
@ -239,9 +249,11 @@ public typealias ActionBlock = () -> ()
|
||||
if let backgroundColor = labelModel.backgroundColor {
|
||||
self.backgroundColor = backgroundColor.uiColor
|
||||
}
|
||||
|
||||
if let accessibilityText = labelModel.accessibilityText {
|
||||
accessibilityLabel = accessibilityText
|
||||
}
|
||||
|
||||
if let fontStyle = labelModel.fontStyle {
|
||||
MFStyler.styleLabel(self, withStyle: fontStyle)
|
||||
MFStyler.styleLabel(self, withStyle: fontStyle, genericScaling: false)
|
||||
@ -264,19 +276,23 @@ public typealias ActionBlock = () -> ()
|
||||
|
||||
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])
|
||||
|
||||
for attribute in attributes {
|
||||
let range = NSRange(location: attribute.location, length: attribute.length)
|
||||
switch attribute {
|
||||
case _ as LabelAttributeUnderlineModel:
|
||||
attributedString.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range)
|
||||
|
||||
case _ as LabelAttributeStrikeThroughModel:
|
||||
attributedString.addAttribute(.strikethroughStyle, value: NSUnderlineStyle.thick.rawValue, range: range)
|
||||
attributedString.addAttribute(.baselineOffset, value: 0, range: range)
|
||||
|
||||
case let colorAtt as LabelAttributeColorModel:
|
||||
if let colorHex = colorAtt.textColor, !colorHex.isEmpty {
|
||||
attributedString.removeAttribute(.foregroundColor, range: range)
|
||||
attributedString.addAttribute(.foregroundColor, value: UIColor.mfGet(forHex: colorHex), range: range)
|
||||
}
|
||||
|
||||
case let imageAtt as LabelAttributeImageModel:
|
||||
var fontSize = font.pointSize
|
||||
if let attributeSize = imageAtt.size {
|
||||
@ -293,6 +309,7 @@ public typealias ActionBlock = () -> ()
|
||||
let mutableString = NSMutableAttributedString()
|
||||
mutableString.append(NSAttributedString(attachment: imageAttachment))
|
||||
attributedString.insert(mutableString, at: imageAtt.location)
|
||||
|
||||
case let fontAtt as LabelAttributeFontModel:
|
||||
if let fontStyle = fontAtt.style {
|
||||
let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle)
|
||||
@ -320,6 +337,7 @@ public typealias ActionBlock = () -> ()
|
||||
}
|
||||
}
|
||||
addActionAttributes(range: range, string: attributedString)
|
||||
|
||||
default:
|
||||
continue
|
||||
}
|
||||
@ -381,8 +399,9 @@ public typealias ActionBlock = () -> ()
|
||||
}
|
||||
|
||||
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,
|
||||
NSAttributedString.Key.foregroundColor: label.textColor as UIColor])
|
||||
let attributedString = NSMutableAttributedString(string: labelText,
|
||||
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 {
|
||||
guard let attributeType = attribute.optionalStringForKey(KeyType),
|
||||
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.
|
||||
@objc public func clearActionableClauses() {
|
||||
|
||||
guard let attributedText = attributedText else { return }
|
||||
let mutableAttributedString = NSMutableAttributedString(attributedString: attributedText)
|
||||
|
||||
|
||||
@ -9,6 +9,9 @@
|
||||
import UIKit
|
||||
|
||||
@objcMembers public class LabelAttributeColorModel: LabelAttributeModel {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
override public class var identifier: String {
|
||||
return "color"
|
||||
@ -16,14 +19,21 @@ import UIKit
|
||||
|
||||
var textColor: String?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case textColor
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,12 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
@objcMembers public class LabelAttributeFontModel: LabelAttributeModel {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
override public class var identifier: String {
|
||||
return "font"
|
||||
}
|
||||
@ -17,17 +22,25 @@ import UIKit
|
||||
var name: String?
|
||||
var size: CGFloat?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case style
|
||||
case name
|
||||
case size
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
self.style = try typeContainer.decodeIfPresent(String.self, forKey: .style)
|
||||
self.name = try typeContainer.decodeIfPresent(String.self, forKey: .name)
|
||||
self.size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size)
|
||||
style = try typeContainer.decodeIfPresent(String.self, forKey: .style)
|
||||
name = try typeContainer.decodeIfPresent(String.self, forKey: .name)
|
||||
size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,10 @@
|
||||
import UIKit
|
||||
|
||||
class LabelAttributeImageModel: LabelAttributeModel {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
override public class var identifier: String {
|
||||
return "image"
|
||||
}
|
||||
@ -18,17 +21,25 @@ class LabelAttributeImageModel: LabelAttributeModel {
|
||||
var name: String?
|
||||
var URL: String?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case size
|
||||
case name
|
||||
case URL
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
self.size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size)
|
||||
self.name = try typeContainer.decodeIfPresent(String.self, forKey: .name)
|
||||
self.URL = try typeContainer.decodeIfPresent(String.self, forKey: .URL)
|
||||
size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size)
|
||||
name = try typeContainer.decodeIfPresent(String.self, forKey: .name)
|
||||
URL = try typeContainer.decodeIfPresent(String.self, forKey: .URL)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,17 @@
|
||||
import Foundation
|
||||
|
||||
@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 {
|
||||
return ""
|
||||
@ -17,6 +28,16 @@ import Foundation
|
||||
var type: String
|
||||
var location: Int
|
||||
var length: Int
|
||||
|
||||
init(_ type: String, _ location: Int, _ length: Int) {
|
||||
self.type = type
|
||||
self.location = location
|
||||
self.length = length
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case type
|
||||
@ -24,11 +45,15 @@ import Foundation
|
||||
case length
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
self.type = try typeContainer.decode(String.self, forKey: .type)
|
||||
self.location = try typeContainer.decode(Int.self, forKey: .location)
|
||||
self.length = try typeContainer.decode(Int.self, forKey: .length)
|
||||
type = try typeContainer.decode(String.self, forKey: .type)
|
||||
location = try typeContainer.decode(Int.self, forKey: .location)
|
||||
length = try typeContainer.decode(Int.self, forKey: .length)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@ -37,5 +62,4 @@ import Foundation
|
||||
try container.encode(location, forKey: .location)
|
||||
try container.encode(length, forKey: .length)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -11,9 +11,7 @@ import Foundation
|
||||
|
||||
@objcMembers public class LabelModel: MoleculeModelProtocol {
|
||||
public static var identifier: String = "label"
|
||||
public var moleculeName: String?
|
||||
public var backgroundColor: Color?
|
||||
|
||||
public var text: String
|
||||
public var accessibilityText: String?
|
||||
public var textColor: String?
|
||||
@ -45,22 +43,25 @@ import Foundation
|
||||
enum AttributeTypeKey: String, CodingKey {
|
||||
case type
|
||||
}
|
||||
|
||||
|
||||
public init(text: String) {
|
||||
self.text = text
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
self.moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName)
|
||||
self.text = try typeContainer.decode(String.self, forKey: .text)
|
||||
self.accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||
self.textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor)
|
||||
self.backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
self.fontStyle = try typeContainer.decodeIfPresent(String.self, forKey: .fontStyle)
|
||||
self.fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName)
|
||||
self.fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize)
|
||||
self.textAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .textAlignment)
|
||||
self.attributes = try typeContainer.decodeModelsIfPresent(codingKey: .attributes, typeCodingKey: AttributeTypeKey.type) as? [LabelAttributeModel]
|
||||
self.html = try typeContainer.decodeIfPresent(String.self, forKey: .html)
|
||||
self.hero = try typeContainer.decodeIfPresent(Int.self, forKey: .hero)
|
||||
self.makeWholeViewClickable = try typeContainer.decodeIfPresent(Bool.self, forKey: .makeWholeViewClickable)
|
||||
text = try typeContainer.decode(String.self, forKey: .text)
|
||||
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||
textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
fontStyle = try typeContainer.decodeIfPresent(String.self, forKey: .fontStyle)
|
||||
fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName)
|
||||
fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize)
|
||||
textAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .textAlignment)
|
||||
attributes = try typeContainer.decodeModelsIfPresent(codingKey: .attributes, typeCodingKey: AttributeTypeKey.type) as? [LabelAttributeModel]
|
||||
html = try typeContainer.decodeIfPresent(String.self, forKey: .html)
|
||||
hero = try typeContainer.decodeIfPresent(Int.self, forKey: .hero)
|
||||
makeWholeViewClickable = try typeContainer.decodeIfPresent(Bool.self, forKey: .makeWholeViewClickable)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
|
||||
@ -232,6 +232,10 @@ import UIKit
|
||||
imageView.animatedImage = nil
|
||||
loadImage(withName: imageModel.image, format: imageModel.imageFormat, width: width as NSNumber?, height: height as NSNumber?, customFallbackImage: imageModel.fallbackImage)
|
||||
}
|
||||
|
||||
if let contentMode = imageModel.contentMode {
|
||||
imageView.contentMode = contentMode
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol functions
|
||||
@ -357,6 +361,10 @@ import UIKit
|
||||
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?) {
|
||||
loadImage(withName: imageName, format: format, width: width, height: height, customFallbackImage: customFallbackImage, completionHandler: defaultCompletionBlock())
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ public typealias ButtonAction = (Button) -> ()
|
||||
if let backgroundColor = model?.backgroundColor {
|
||||
self.backgroundColor = backgroundColor.uiColor
|
||||
}
|
||||
|
||||
|
||||
guard let model = model as? ButtonModelProtocol else { return }
|
||||
isEnabled = model.enabled
|
||||
set(with: model.action, delegateObject: delegateObject, additionalData: additionalData)
|
||||
|
||||
@ -28,6 +28,8 @@ import UIKit
|
||||
|
||||
private var heroAccessoryCenter: CGPoint?
|
||||
|
||||
private var initialSetupPerformed = false
|
||||
|
||||
// MARK: - Styling
|
||||
open func style(with styleString: String?) {
|
||||
guard let styleString = styleString else {
|
||||
@ -102,12 +104,19 @@ import UIKit
|
||||
// MARK: - Inits
|
||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
setupView()
|
||||
initialSetup()
|
||||
}
|
||||
|
||||
public required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
setupView()
|
||||
initialSetup()
|
||||
}
|
||||
|
||||
public func initialSetup() {
|
||||
if !initialSetupPerformed {
|
||||
initialSetupPerformed = true
|
||||
setupView()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - MFViewProtocol
|
||||
@ -151,10 +160,6 @@ import UIKit
|
||||
self.listItemModel = model
|
||||
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.
|
||||
if !customAccessoryView {
|
||||
if let _ = model.action, !(model.hideArrow ?? false) {
|
||||
@ -169,11 +174,15 @@ import UIKit
|
||||
addSeparatorsIfNeeded()
|
||||
bottomSeparatorView?.setWithModel(separator, nil, nil)
|
||||
}
|
||||
|
||||
if let moleculeModel = model as? MoleculeModelProtocol,
|
||||
let backgroundColor = moleculeModel.backgroundColor {
|
||||
self.backgroundColor = backgroundColor.uiColor
|
||||
}
|
||||
}
|
||||
|
||||
open func reset() {
|
||||
molecule?.reset?()
|
||||
styleStandard()
|
||||
backgroundColor = .white
|
||||
}
|
||||
|
||||
@ -9,41 +9,35 @@
|
||||
import Foundation
|
||||
|
||||
extension MFViewController: MoleculeDelegateProtocol {
|
||||
public func getModuleWithName(_ name: String?) -> [AnyHashable : Any]? {
|
||||
guard let name = name else {
|
||||
return nil
|
||||
}
|
||||
|
||||
public func getModuleWithName(_ name: String?) -> [AnyHashable: Any]? {
|
||||
guard let name = name else { return nil }
|
||||
|
||||
return loadObject?.modulesJSON?.optionalDictionaryForKey(name)
|
||||
}
|
||||
|
||||
public func getModuleWithName(_ moduleName: String) -> MoleculeModelProtocol? {
|
||||
guard let moduleJSON = loadObject?.modulesJSON?.optionalDictionaryForKey(moduleName),
|
||||
public func getModuleWithName(_ moleculeName: String) -> MoleculeModelProtocol? {
|
||||
guard let moduleJSON = loadObject?.modulesJSON?.optionalDictionaryForKey(moleculeName),
|
||||
let moleculeName = moduleJSON.optionalStringForKey("moleculeName"),
|
||||
let modelType = ModelRegistry.getType(for: moleculeName) as? MoleculeModelProtocol.Type else {
|
||||
return nil
|
||||
}
|
||||
let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self)
|
||||
else { return nil }
|
||||
|
||||
do {
|
||||
return try modelType.decode(jsonDict: moduleJSON)
|
||||
return try modelType.decode(jsonDict: moduleJSON) as? MoleculeModelProtocol
|
||||
} catch {
|
||||
MVMCoreUILoggingHandler.logDebugMessage(withDelegate: "error: \(error)")
|
||||
}
|
||||
|
||||
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) {
|
||||
// Do nothing
|
||||
}
|
||||
@objc public func addMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { }
|
||||
|
||||
@objc public func removeMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||
// Do nothing
|
||||
}
|
||||
@objc public func removeMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { }
|
||||
}
|
||||
|
||||
public extension MFViewController {
|
||||
@objc func parsePageJSON() throws {
|
||||
}
|
||||
@objc func parsePageJSON() throws { }
|
||||
}
|
||||
|
||||
@ -68,9 +68,8 @@ open class ThreeLayerTableViewController: MFProgrammaticTableViewController {
|
||||
|
||||
open override func updateViewConstraints() {
|
||||
super.updateViewConstraints()
|
||||
guard let tableView = tableView else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let tableView = tableView else { return }
|
||||
|
||||
let minimumSpace: CGFloat = minimumFillSpace()
|
||||
var currentSpace: CGFloat = 0
|
||||
@ -90,9 +89,8 @@ open class ThreeLayerTableViewController: MFProgrammaticTableViewController {
|
||||
totalMinimumSpace += minimumSpace
|
||||
}
|
||||
|
||||
guard fillTop || fillBottom else {
|
||||
return
|
||||
}
|
||||
guard fillTop || fillBottom else { return }
|
||||
|
||||
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.
|
||||
@ -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.
|
||||
headerView.setNeedsLayout()
|
||||
headerView.layoutIfNeeded()
|
||||
MVMCoreUIUtility.sizeView(toFit: headerView)
|
||||
let tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: MVMCoreUIUtility.getWidth(), height: headerView.frame.height))
|
||||
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.
|
||||
}
|
||||
}
|
||||
@ -9,36 +9,52 @@
|
||||
import Foundation
|
||||
|
||||
public extension NSLayoutConstraint {
|
||||
static func pinSubviewsCenter(leftView: UIView, rightView: UIView) {
|
||||
guard let superView = leftView.superview else {
|
||||
return
|
||||
|
||||
/// Pins the views vertically in the super view, allowing the super to expand depending on the tallest view. Shorter views are aligned center.
|
||||
static func pinViewsVerticalExpandableAlignCenter(_ views: [UIView]) {
|
||||
for view in views {
|
||||
guard let superView = view.superview else {
|
||||
return
|
||||
}
|
||||
view.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true
|
||||
view.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true
|
||||
superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true
|
||||
|
||||
var constraint = view.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor)
|
||||
constraint.priority = .defaultLow
|
||||
constraint.isActive = true
|
||||
|
||||
constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
||||
constraint.priority = .defaultLow
|
||||
constraint.isActive = true
|
||||
}
|
||||
leftView.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true
|
||||
leftView.leftAnchor.constraint(equalTo: superView.layoutMarginsGuide.leftAnchor).isActive = true
|
||||
leftView.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true
|
||||
superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: leftView.bottomAnchor).isActive = true
|
||||
}
|
||||
|
||||
/// Pins the views vertically in the super view, allowing the super to expand depending on the tallest view. Shorter views are aligned top.
|
||||
static func pinViewsVerticalExpandableAlignTop(_ views: [UIView]) {
|
||||
for view in views {
|
||||
guard let superView = view.superview else {
|
||||
return
|
||||
}
|
||||
view.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor).isActive = true
|
||||
superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true
|
||||
|
||||
var constraint = leftView.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor)
|
||||
constraint.priority = .defaultLow
|
||||
constraint.isActive = true
|
||||
|
||||
constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: leftView.bottomAnchor)
|
||||
constraint.priority = .defaultLow
|
||||
constraint.isActive = true
|
||||
|
||||
rightView.leftAnchor.constraint(greaterThanOrEqualTo: leftView.rightAnchor, constant: 16).isActive = true
|
||||
|
||||
rightView.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true
|
||||
superView.layoutMarginsGuide.rightAnchor.constraint(equalTo: rightView.rightAnchor).isActive = true
|
||||
rightView.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true
|
||||
superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: rightView.bottomAnchor).isActive = true
|
||||
|
||||
constraint = rightView.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor)
|
||||
constraint.priority = .defaultLow
|
||||
constraint.isActive = true
|
||||
|
||||
constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: rightView.bottomAnchor)
|
||||
constraint.priority = .defaultLow
|
||||
constraint.isActive = true
|
||||
let constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
||||
constraint.priority = .defaultLow
|
||||
constraint.isActive = true
|
||||
}
|
||||
}
|
||||
|
||||
/// Pins a view to the left and a view to the right, flexible space in between. The super can expand depending on the taller view. Shorter views are aligned top if alignTop true, else aligned center.
|
||||
static func pinViews(leftView: UIView, rightView: UIView, alignTop: Bool) {
|
||||
guard let superView = leftView.superview else { return }
|
||||
if alignTop {
|
||||
pinViewsVerticalExpandableAlignTop([leftView, rightView])
|
||||
} else {
|
||||
pinViewsVerticalExpandableAlignCenter([leftView, rightView])
|
||||
}
|
||||
leftView.leadingAnchor.constraint(equalTo: superView.layoutMarginsGuide.leadingAnchor).isActive = true
|
||||
superView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightView.trailingAnchor).isActive = true
|
||||
rightView.leftAnchor.constraint(greaterThanOrEqualTo: leftView.rightAnchor, constant: PaddingHorizontalBetweenRelatedItems).isActive = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,24 +12,52 @@ public typealias ColorHexTuple = (uiColor: UIColor, hex: String)
|
||||
|
||||
|
||||
extension UIColor {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Convenience Dictionary
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Dictionary to access brand approved colors by name.
|
||||
public static let names: [String: ColorHexTuple] = ["black": (.mvmBlack, "#000000"),
|
||||
"white": (.mvmWhite, "#FFFFFF"),
|
||||
"red": (.mvmRed, "#D52B1E"),
|
||||
"orange": (.mvmOrange, "#CC4D0F"),
|
||||
"green": (.mvmGreen, "#008631"),
|
||||
"blue": (.mvmBlue, "#007AB8"),
|
||||
"blueGradient": (.mvmBlueGradient, "#007AB8"),
|
||||
"pink": (.mvmPink, "#D90368"),
|
||||
"pink33": (.mvmPink33, "#F2ABCD"),
|
||||
"pink66": (.mvmPink66, "#E6589B"),
|
||||
"pinkShade1": (.mvmPinkShade1, "#B31C63"),
|
||||
"pinkShade2": (.mvmPinkShade2, "#830842"),
|
||||
"purple": (.mvmPurple, "#8C00AC"),
|
||||
"purple33": (.mvmPurple33, "#D9ABE4"),
|
||||
"purple66": (.mvmPurple66, "#B356C8"),
|
||||
"purpleShade1": (.mvmPurpleShade1, "#6C177F"),
|
||||
"purpleShade2": (.mvmPurpleShade2, "#4A0E58"),
|
||||
"green": (.mvmGreen, "#008330"),
|
||||
"green33": (.mvmGreen33, "#ABE4BF"),
|
||||
"green66": (.mvmGreen66, "#57C880"),
|
||||
"greenShade1": (.mvmGreenShade1, "#178437"),
|
||||
"greenShade2": (.mvmGreenShade2, "#0F5B25"),
|
||||
"orange": (.mvmOrange, "#ED7000"),
|
||||
"orange66": (.mvmOrange66, "#F3A157"),
|
||||
"orange33": (.mvmOrange33, "#F9D0AB"),
|
||||
"orangeShade1": (.mvmOrangeShade1, "#CB5F00"),
|
||||
"orangeShade2": (.mvmOrangeShade2, "#984700"),
|
||||
"orangeAA": (.mvmOrangeAA, "#CC4D0F"),
|
||||
"blue": (.mvmBlue, "#0077B4"),
|
||||
"blue33": (.mvmBlue33, "#57B1DF"),
|
||||
"blue66": (.mvmBlue66, "#57B1DF"),
|
||||
"blueShade1": (.mvmBlueShade1, "#136598"),
|
||||
"blueShade2": (.mvmBlueShade2, "#0B4467"),
|
||||
"yellow": (.mvmYellow, "#FFBC3D"),
|
||||
"yellow33": (.mvmYellow33, "#FFE9BF"),
|
||||
"yellow66": (.mvmYellow66, "#FFD37F"),
|
||||
"yellowShade1": (.mvmYellowShade1, "#CC9630"),
|
||||
"yellowShade2": (.mvmYellowShade2, "#997126"),
|
||||
"coolGray1": (.mvmCoolGray1, "#F6F6F6"),
|
||||
"coolGray3": (.mvmCoolGray3, "#D8DADA"),
|
||||
"coolGray6": (.mvmCoolGray6, "#747676"),
|
||||
"coolGray10": (.mvmCoolGray10, "#333333"),
|
||||
"vzupGold": (.vzupGold, "#B89B56"),
|
||||
"vzupYellow1": (.vzupYellow1, "#F9D542"),
|
||||
"vzupYellow2": (.vzupYellow2, "#F4CA53"),
|
||||
"vzupYellow3": (.vzupYellow3, "#CC9B2D")]
|
||||
"upGold1": (.vzupGold1, "#F9D542"),
|
||||
"upGold2": (.vzupGold2, "#F4CA53"),
|
||||
"upGold3": (.vzupGold3, "#CC9B2D")]
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Brand
|
||||
@ -41,24 +69,134 @@ extension UIColor {
|
||||
/// HEX: #FFFFFF
|
||||
public static let mvmWhite = UIColor.white
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Red
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #D52B1E
|
||||
public static let mvmRed = UIColor.color8Bits(red: 213, green: 43, blue: 30)
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Pink
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #D90368
|
||||
public static let mvmPink = UIColor.color8Bits(red: 217, green: 3, blue: 104)
|
||||
|
||||
/// HEX: #F2ABCD
|
||||
public static let mvmPink33 = UIColor.color8Bits(red: 242, green: 171, blue: 205)
|
||||
|
||||
/// HEX: #E6589B
|
||||
public static let mvmPink66 = UIColor.color8Bits(red: 230, green: 88, blue: 155)
|
||||
|
||||
/// HEX: #B31C63
|
||||
public static let mvmPinkShade1 = UIColor.color8Bits(red: 179, green: 28, blue: 99)
|
||||
|
||||
/// HEX: #830842
|
||||
public static let mvmPinkShade2 = UIColor.color8Bits(red: 131, green: 8, blue: 66)
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Purple
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #8C00AC
|
||||
public static let mvmPurple = UIColor.color8Bits(red: 140, green: 0, blue: 172)
|
||||
|
||||
/// HEX: #D9ABE4
|
||||
public static let mvmPurple33 = UIColor.color8Bits(red: 217, green: 171, blue: 228)
|
||||
|
||||
/// HEX: #B356C8
|
||||
public static let mvmPurple66 = UIColor.color8Bits(red: 179, green: 86, blue: 200)
|
||||
|
||||
/// HEX: #6C177F
|
||||
public static let mvmPurpleShade1 = UIColor.color8Bits(red: 108, green: 23, blue: 127)
|
||||
|
||||
/// HEX: #4A0E58
|
||||
public static let mvmPurpleShade2 = UIColor.color8Bits(red: 74, green: 14, blue: 88)
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Orange
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #ED7000
|
||||
public static let mvmOrange = UIColor.color8Bits(red: 237, green: 112, blue: 0)
|
||||
|
||||
/// HEX: #CC4D0F
|
||||
public static let mvmOrange = UIColor.color8Bits(red: 204, green: 77, blue: 15)
|
||||
public static let mvmOrangeAA = UIColor.color8Bits(red: 204, green: 77, blue: 15)
|
||||
|
||||
/// HEX: #008631
|
||||
public static let mvmGreen = UIColor.color8Bits(red: 0, green: 134, blue: 49)
|
||||
/// HEX: #F9D0AB
|
||||
public static let mvmOrange33 = UIColor.color8Bits(red: 249, green: 208, blue: 171)
|
||||
|
||||
/// HEX: #007AB8
|
||||
public static let mvmBlue = UIColor.color8Bits(red: 0, green: 122, blue: 184)
|
||||
/// HEX: #F3A157
|
||||
public static let mvmOrange66 = UIColor.color8Bits(red: 243, green: 161, blue: 87)
|
||||
|
||||
/// HEX: #007AB8
|
||||
public static let mvmBlueGradient = UIColor.color8Bits(red: 0, green: 122, blue: 184)
|
||||
/// HEX: #CB5F00
|
||||
public static let mvmOrangeShade1 = UIColor.color8Bits(red: 203, green: 95, blue: 0)
|
||||
|
||||
/// HEX: #984700
|
||||
public static let mvmOrangeShade2 = UIColor.color8Bits(red: 152, green: 71, blue: 0)
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Green
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #008330
|
||||
public static let mvmGreen = UIColor.color8Bits(red: 0, green: 134, blue: 48)
|
||||
|
||||
/// HEX: #ABE4BF
|
||||
public static let mvmGreen33 = UIColor.color8Bits(red: 171, green: 228, blue: 191)
|
||||
|
||||
/// HEX: #57C880
|
||||
public static let mvmGreen66 = UIColor.color8Bits(red: 87, green: 200, blue: 128)
|
||||
|
||||
/// HEX: #178437
|
||||
public static let mvmGreenShade1 = UIColor.color8Bits(red: 23, green: 132, blue: 55)
|
||||
|
||||
/// HEX: #0F5B25
|
||||
public static let mvmGreenShade2 = UIColor.color8Bits(red: 15, green: 91, blue: 37)
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Blue
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #0077B4
|
||||
public static let mvmBlue = UIColor.color8Bits(red: 0, green: 119, blue: 180)
|
||||
|
||||
/// HEX: #57B1DF
|
||||
public static let mvmBlue33 = UIColor.color8Bits(red: 87, green: 177, blue: 223)
|
||||
|
||||
/// HEX: #57B1DF
|
||||
public static let mvmBlue66 = UIColor.color8Bits(red: 87, green: 177, blue: 223)
|
||||
|
||||
/// HEX: #136598
|
||||
public static let mvmBlueShade1 = UIColor.color8Bits(red: 19, green: 101, blue: 152)
|
||||
|
||||
/// HEX: #0B4467
|
||||
public static let mvmBlueShade2 = UIColor.color8Bits(red: 11, green: 68, blue: 103)
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Yellow
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #FFBC3D
|
||||
public static let mvmYellow = UIColor.color8Bits(red: 255, green: 188, blue: 61)
|
||||
|
||||
/// HEX: #FFE9BF
|
||||
public static let mvmYellow33 = UIColor.color8Bits(red: 255, green: 233, blue: 191)
|
||||
|
||||
/// HEX: #FFD37F
|
||||
public static let mvmYellow66 = UIColor.color8Bits(red: 255, green: 211, blue: 127)
|
||||
|
||||
/// HEX: #CC9630
|
||||
public static let mvmYellowShade1 = UIColor.color8Bits(red: 204, green: 150, blue: 48)
|
||||
|
||||
/// HEX: #997126
|
||||
public static let mvmYellowShade2 = UIColor.color8Bits(red: 153, green: 113, blue: 38)
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Gray
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #F6F6F6
|
||||
public static let mvmCoolGray1 = UIColor.grayscale(rgb: 246)
|
||||
|
||||
@ -75,17 +213,14 @@ extension UIColor {
|
||||
// MARK: - VZ UP Brand
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: #B89B56
|
||||
public static let vzupGold = UIColor.color8Bits(red: 184, green: 155, blue: 68)
|
||||
|
||||
/// HEX: #F9D542
|
||||
public static let vzupYellow1 = UIColor.color8Bits(red: 249, green: 213, blue: 66)
|
||||
public static let vzupGold1 = UIColor.color8Bits(red: 249, green: 213, blue: 66)
|
||||
|
||||
/// HEX: #F4CA53
|
||||
public static let vzupYellow2 = UIColor.color8Bits(red: 244, green: 202, blue: 83)
|
||||
public static let vzupGold2 = UIColor.color8Bits(red: 244, green: 202, blue: 83)
|
||||
|
||||
/// HEX: #CC9B2D
|
||||
public static let vzupYellow3 = UIColor.color8Bits(red: 204, green: 155, blue: 45)
|
||||
public static let vzupGold3 = UIColor.color8Bits(red: 204, green: 155, blue: 45)
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Functions
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
+ (nonnull UIColor *)mfLightSilver;
|
||||
+ (nonnull UIColor *)mfDarkSilver;
|
||||
+ (nonnull UIColor *)mfTomatoRed;
|
||||
+ (nonnull UIColor *)mvmOrange;
|
||||
+ (nonnull UIColor *)mfPumpkinColor;
|
||||
+ (nonnull UIColor *)mfShamrock;
|
||||
+ (nonnull UIColor *)mfCerulean;
|
||||
|
||||
@ -37,7 +37,6 @@
|
||||
return [UIColor mfColor8bitsWithRed:198 green:197 blue:197 alpha:1.0];
|
||||
}
|
||||
|
||||
|
||||
+ (nonnull UIColor *)mfPrimaryButtonHighlightBlackColor {
|
||||
return [UIColor mfColor8bitsWithRed:51 green:51 blue:51 alpha:1.0];
|
||||
}
|
||||
@ -54,6 +53,10 @@
|
||||
return [UIColor mfColor8bitsWithRed:204 green:77 blue:15 alpha:1.0];
|
||||
}
|
||||
|
||||
+ (nonnull UIColor *)mvmOrange {
|
||||
return [UIColor mfColor8bitsWithRed:237 green:112 blue:0 alpha:1.0];
|
||||
}
|
||||
|
||||
+ (nonnull UIColor *)mfShamrock {
|
||||
return [UIColor mfColor8bitsWithRed:0 green:134 blue:49 alpha:1.0];
|
||||
}
|
||||
|
||||
98
MVMCoreUI/Categories/UIContentMode+Extension.swift
Normal file
98
MVMCoreUI/Categories/UIContentMode+Extension.swift
Normal file
@ -0,0 +1,98 @@
|
||||
//
|
||||
// UIContentMode+Extension.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 2/17/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum ContentModeError: Error {
|
||||
case notAContentMode
|
||||
}
|
||||
|
||||
extension UIView.ContentMode: RawRepresentable {
|
||||
|
||||
init?(rawValue: String) {
|
||||
switch rawValue {
|
||||
case "scaleToFill":
|
||||
self = .scaleToFill
|
||||
case "scaleAspectFit":
|
||||
self = .scaleAspectFit
|
||||
case "scaleAspectFill":
|
||||
self = .scaleAspectFill
|
||||
case "redraw":
|
||||
self = .redraw
|
||||
case "center":
|
||||
self = .center
|
||||
case "top":
|
||||
self = .top
|
||||
case "bottom":
|
||||
self = .bottom
|
||||
case "left":
|
||||
self = .left
|
||||
case "right":
|
||||
self = .right
|
||||
case "topLeft":
|
||||
self = .topLeft
|
||||
case "topRight":
|
||||
self = .topRight
|
||||
case "bottomLeft":
|
||||
self = .bottomLeft
|
||||
case "bottomRight":
|
||||
self = .bottomRight
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var rawValueString: String {
|
||||
switch self {
|
||||
case .scaleToFill:
|
||||
return "scaleToFill"
|
||||
case .scaleAspectFit:
|
||||
return "scaleAspectFit"
|
||||
case .scaleAspectFill:
|
||||
return "scaleAspectFill"
|
||||
case .redraw:
|
||||
return "redraw"
|
||||
case .center:
|
||||
return "center"
|
||||
case .top:
|
||||
return "top"
|
||||
case .bottom:
|
||||
return "bottom"
|
||||
case .left:
|
||||
return "left"
|
||||
case .right:
|
||||
return "right"
|
||||
case .topLeft:
|
||||
return "topLeft"
|
||||
case .topRight:
|
||||
return "topRight"
|
||||
case .bottomLeft:
|
||||
return "bottomLeft"
|
||||
case .bottomRight:
|
||||
return "bottomRight"
|
||||
@unknown default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension UIView.ContentMode: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.singleValueContainer()
|
||||
let string = try typeContainer.decode(String.self)
|
||||
guard let mode = UIView.ContentMode(rawValue: string) else {
|
||||
throw ContentModeError.notAContentMode
|
||||
}
|
||||
self = mode
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
try container.encode(rawValueString)
|
||||
}
|
||||
}
|
||||
@ -48,7 +48,8 @@ public class ContainerModel: ContainerModelProtocol, Codable {
|
||||
try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: horizontalAlignment), forKey: .horizontalAlignment)
|
||||
try container.encodeIfPresent(useHorizontalMargins, forKey: .useHorizontalMargins)
|
||||
try container.encodeIfPresent(useVerticalMargins, forKey: .useVerticalMargins)
|
||||
try container.encodeIfPresent(topMarginPadding, forKey: .topMarginPadding)
|
||||
try container.encodeIfPresent(bottomMarginPadding, forKey: .bottomMarginPadding)
|
||||
// TODO: can add this back once we have type erasures.
|
||||
//try container.encodeIfPresent(topMarginPadding, forKey: .topMarginPadding)
|
||||
//try container.encodeIfPresent(bottomMarginPadding, forKey: .bottomMarginPadding)
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ public final class Color: Codable {
|
||||
// MARK: - Class Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
init(uiColor: UIColor) {
|
||||
public init(uiColor: UIColor) {
|
||||
self.uiColor = uiColor
|
||||
hex = UIColor.hexString(for: uiColor) ?? ""
|
||||
determineRGBA()
|
||||
|
||||
@ -8,7 +8,9 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
extension KeyedDecodingContainer where Key : CodingKey {
|
||||
|
||||
extension KeyedDecodingContainer where Key: CodingKey {
|
||||
|
||||
private enum TypeCodingKey: String, CodingKey {
|
||||
case moleculeName
|
||||
}
|
||||
|
||||
@ -8,7 +8,8 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
public protocol CarouselItemModelProtocol: ContainerModelProtocol, MoleculeModelProtocol {
|
||||
var peakingUI: Bool? {get}
|
||||
var peakingArrowColor: Color? {get}
|
||||
var peakingUI: Bool? { get }
|
||||
var peakingArrowColor: Color? { get }
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
public protocol CarouselPagingModelProtocol: MoleculeModelProtocol {
|
||||
var position: Float? {get}
|
||||
var position: Float? { get }
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
public protocol ContainerModelProtocol {
|
||||
var horizontalAlignment: UIStackView.Alignment? { get set }
|
||||
var verticalAlignment: UIStackView.Alignment? { get set }
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
public protocol EnableableModelProtocol {
|
||||
var enabled: Bool { get set }
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
public protocol FormModelProtocol: Model {
|
||||
var required: Bool? { get }
|
||||
var fieldKey: String? { get }
|
||||
|
||||
@ -8,7 +8,8 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol ListItemModelProtocol: ContainerModelProtocol, MoleculeModelProtocol {
|
||||
|
||||
public protocol ListItemModelProtocol: ContainerModelProtocol {
|
||||
var line: LineModel? { get set }
|
||||
var action: ActionModelProtocol? { get set }
|
||||
var hideArrow: Bool? { get set }
|
||||
@ -16,20 +17,15 @@ public protocol ListItemModelProtocol: ContainerModelProtocol, MoleculeModelProt
|
||||
}
|
||||
|
||||
// Not a strict requirement.
|
||||
extension ListItemModelProtocol {
|
||||
public var action: ActionModelProtocol? {
|
||||
get {
|
||||
return nil
|
||||
}
|
||||
set {
|
||||
}
|
||||
public extension ListItemModelProtocol {
|
||||
|
||||
var action: ActionModelProtocol? {
|
||||
get { return nil }
|
||||
set { }
|
||||
}
|
||||
|
||||
public var style: String? {
|
||||
get {
|
||||
return nil
|
||||
}
|
||||
set {
|
||||
}
|
||||
var style: String? {
|
||||
get { return nil }
|
||||
set { }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,22 @@
|
||||
import Foundation
|
||||
|
||||
|
||||
public protocol MoleculeModelProtocol: Model {
|
||||
var moleculeName: String? { get }
|
||||
var backgroundColor: Color? { get set}
|
||||
}
|
||||
|
||||
extension MoleculeModelProtocol {
|
||||
public var moleculeName: String? {
|
||||
public extension MoleculeModelProtocol {
|
||||
|
||||
var moleculeName: String? {
|
||||
get { return Self.identifier }
|
||||
}
|
||||
|
||||
static var categoryName: String {
|
||||
return "\(MoleculeModelProtocol.self)"
|
||||
}
|
||||
|
||||
static var categoryCodingKey: String {
|
||||
return "moleculeName"
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,8 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol PageModelProtocol: Model {
|
||||
|
||||
public protocol PageModelProtocol {
|
||||
var pageType: String { get set }
|
||||
var screenHeading: String? { get set }
|
||||
var isAtomicTabs: Bool? { get set }
|
||||
|
||||
@ -8,12 +8,22 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol TemplateModelProtocol: PageModelProtocol {
|
||||
|
||||
public protocol TemplateModelProtocol: PageModelProtocol, Model {
|
||||
var template: String { get }
|
||||
}
|
||||
|
||||
extension TemplateModelProtocol {
|
||||
public var template: String {
|
||||
public extension TemplateModelProtocol {
|
||||
|
||||
var template: String {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,13 +10,14 @@ import UIKit
|
||||
|
||||
@objcMembers open class ImageHeadlineBody: View {
|
||||
let headlineBody = HeadlineBody(frame: .zero)
|
||||
let imageView = MFLoadImageView()
|
||||
let imageView = MFLoadImageView(pinnedEdges: .all)
|
||||
var constraintBetweenImageLabelsConstant: CGFloat = 16
|
||||
var constraintBetweenImageLabels: NSLayoutConstraint?
|
||||
|
||||
// MARK: - MFViewProtocol
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
guard subviews.count == 0 else {
|
||||
return
|
||||
}
|
||||
@ -26,23 +27,9 @@ import UIKit
|
||||
addSubview(headlineBody)
|
||||
addSubview(imageView)
|
||||
|
||||
headlineBody.topAnchor.constraint(equalTo: topAnchor).isActive = true
|
||||
NSLayoutConstraint.pinViewsVerticalExpandableAlignCenter([imageView, headlineBody])
|
||||
rightAnchor.constraint(equalTo: headlineBody.rightAnchor).isActive = true
|
||||
bottomAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor).isActive = true
|
||||
var constraint = bottomAnchor.constraint(equalTo: headlineBody.bottomAnchor)
|
||||
constraint.priority = .defaultLow
|
||||
constraint.isActive = true
|
||||
|
||||
imageView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
|
||||
imageView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
|
||||
imageView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor).isActive = true
|
||||
bottomAnchor.constraint(greaterThanOrEqualTo: imageView.bottomAnchor).isActive = true
|
||||
constraint = bottomAnchor.constraint(equalTo: imageView.bottomAnchor)
|
||||
constraint.priority = UILayoutPriority(rawValue: 200)
|
||||
constraint.isActive = true
|
||||
constraint = imageView.topAnchor.constraint(equalTo: topAnchor)
|
||||
constraint.priority = UILayoutPriority(rawValue: 200)
|
||||
constraint.isActive = true
|
||||
|
||||
constraintBetweenImageLabels = headlineBody.leadingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: constraintBetweenImageLabelsConstant)
|
||||
constraintBetweenImageLabels?.isActive = true
|
||||
|
||||
@ -8,12 +8,12 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
@objcMembers open class TwoButtonView: ViewConstrainingView {
|
||||
open var primaryButton: PrimaryButton? = PrimaryButton.button()
|
||||
open var secondaryButton: PrimaryButton? = PrimaryButton.button()
|
||||
open var viewForButtons: UIView?
|
||||
public var heightConstraint: NSLayoutConstraint?
|
||||
|
||||
@objcMembers open class TwoButtonView: View, MVMCoreUIViewConstrainingProtocol {
|
||||
open var primaryButton: PillButton = PillButton()
|
||||
open var secondaryButton: PillButton = PillButton()
|
||||
private var stack = UIStackView()
|
||||
private var equalWidthConstraint: NSLayoutConstraint?
|
||||
|
||||
public init() {
|
||||
super.init(frame: .zero)
|
||||
}
|
||||
@ -26,289 +26,100 @@ import UIKit
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public func setDefaultCustom() {
|
||||
primaryButton?.setAsStandardCustom()
|
||||
secondaryButton?.setAsSecondaryCustom()
|
||||
public func setDefault() {
|
||||
primaryButton.stylePrimary()
|
||||
secondaryButton.styleSecondary()
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||
self.primaryButton?.updateView(size)
|
||||
self.secondaryButton?.updateView(size)
|
||||
})
|
||||
self.primaryButton.updateView(size)
|
||||
self.secondaryButton.updateView(size)
|
||||
}
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
setupWithTwoButtons()
|
||||
secondaryButton?.bordered = true
|
||||
|
||||
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(stack)
|
||||
stack.addArrangedSubview(secondaryButton)
|
||||
stack.addArrangedSubview(primaryButton)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
|
||||
stack.axis = .horizontal
|
||||
stack.spacing = 10
|
||||
equalWidthConstraint = secondaryButton.widthAnchor.constraint(equalTo: primaryButton.widthAnchor, multiplier: 1)
|
||||
equalWidthConstraint?.isActive = true
|
||||
}
|
||||
|
||||
// MARK: - Stack Manipulation
|
||||
public func showPrimaryButton() {
|
||||
if !stack.arrangedSubviews.contains(primaryButton) {
|
||||
stack.addArrangedSubview(primaryButton)
|
||||
primaryButton.isHidden = false
|
||||
}
|
||||
if secondaryButton.superview != nil {
|
||||
equalWidthConstraint?.isActive = true
|
||||
}
|
||||
}
|
||||
|
||||
public func showSecondaryButton() {
|
||||
if !stack.arrangedSubviews.contains(secondaryButton) {
|
||||
stack.insertArrangedSubview(secondaryButton, at: 0)
|
||||
secondaryButton.isHidden = false
|
||||
}
|
||||
if primaryButton.superview != nil {
|
||||
equalWidthConstraint?.isActive = true
|
||||
}
|
||||
}
|
||||
|
||||
public func hidePrimaryButton() {
|
||||
if primaryButton.superview != nil {
|
||||
stack.removeArrangedSubview(primaryButton)
|
||||
primaryButton.isHidden = true
|
||||
}
|
||||
equalWidthConstraint?.isActive = false
|
||||
}
|
||||
|
||||
public func hideSecondaryButton() {
|
||||
if secondaryButton.superview != nil {
|
||||
stack.removeArrangedSubview(secondaryButton)
|
||||
secondaryButton.isHidden = true
|
||||
}
|
||||
equalWidthConstraint?.isActive = false
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
let primaryButtonMap = json?.optionalDictionaryForKey("primaryButton")
|
||||
let secondaryButtonMap = json?.optionalDictionaryForKey("secondaryButton")
|
||||
set(primaryButtonJSON: primaryButtonMap, secondaryButtonJSON: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
primaryButton?.setAsStandardCustom()
|
||||
secondaryButton?.setAsSecondaryCustom()
|
||||
setDefault()
|
||||
}
|
||||
|
||||
// MARK: - Constraining
|
||||
func createPrimaryButton() {
|
||||
if primaryButton == nil {
|
||||
primaryButton = PrimaryButton.button()
|
||||
}
|
||||
}
|
||||
|
||||
func createSecondaryButton() {
|
||||
if secondaryButton == nil {
|
||||
secondaryButton = PrimaryButton.button()
|
||||
secondaryButton?.bordered = true
|
||||
}
|
||||
}
|
||||
|
||||
func removeButtons() {
|
||||
viewForButtons?.removeFromSuperview()
|
||||
primaryButton?.removeFromSuperview()
|
||||
secondaryButton?.removeFromSuperview()
|
||||
viewForButtons = nil
|
||||
secondaryButton = nil
|
||||
primaryButton = nil
|
||||
}
|
||||
|
||||
open func setupConstraintsForViewWithButtons() {
|
||||
guard let viewForButtons = viewForButtons,
|
||||
let primaryButton = primaryButton,
|
||||
let secondaryButton = secondaryButton
|
||||
else { return }
|
||||
|
||||
viewForButtons.addSubview(primaryButton)
|
||||
viewForButtons.addSubview(secondaryButton)
|
||||
secondaryButton.widthAnchor.constraint(equalTo: primaryButton.widthAnchor, multiplier: 1).isActive = true
|
||||
NSLayoutConstraint.constraintPinSubview(secondaryButton, pinTop: true, pinBottom: true, pinLeft: true, pinRight: false)
|
||||
NSLayoutConstraint.constraintPinSubview(primaryButton, pinTop: true, pinBottom: true, pinLeft: false, pinRight: true)
|
||||
let constraint = primaryButton.leadingAnchor.constraint(equalTo: secondaryButton.trailingAnchor, constant: 10)
|
||||
constraint.priority = UILayoutPriority(900)
|
||||
constraint.isActive = true
|
||||
}
|
||||
|
||||
func setupWithTwoButtons() {
|
||||
guard viewForButtons == nil else {
|
||||
return
|
||||
}
|
||||
let viewForButtons = MVMCoreUICommonViewsUtility.commonView()
|
||||
addSubview(viewForButtons)
|
||||
self.viewForButtons = viewForButtons
|
||||
|
||||
pinView(toSuperView: viewForButtons)
|
||||
alignCenterHorizontal()
|
||||
createPrimaryButton()
|
||||
createSecondaryButton()
|
||||
setupConstraintsForViewWithButtons()
|
||||
}
|
||||
|
||||
open func setupWithPrimaryButton() {
|
||||
guard primaryButton == nil && secondaryButton == nil else {
|
||||
return
|
||||
}
|
||||
createPrimaryButton()
|
||||
if let primaryButton = primaryButton {
|
||||
addSubview(primaryButton)
|
||||
pinView(toSuperView: primaryButton)
|
||||
alignCenterHorizontal()
|
||||
}
|
||||
}
|
||||
|
||||
open func setupWithSecondaryButton() {
|
||||
guard secondaryButton == nil && primaryButton == nil else {
|
||||
return
|
||||
}
|
||||
createSecondaryButton()
|
||||
if let secondaryButton = secondaryButton {
|
||||
addSubview(secondaryButton)
|
||||
pinView(toSuperView: secondaryButton)
|
||||
alignCenterHorizontal()
|
||||
}
|
||||
}
|
||||
|
||||
/// Legacy
|
||||
func setupUI(withPrimaryButtonMap primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?) {
|
||||
setupUI(primaryButtonShowing: primaryButtonMap != nil, secondaryButtonShowing: secondaryButtonMap != nil)
|
||||
}
|
||||
|
||||
func setupUI(primaryButtonShowing: Bool, secondaryButtonShowing: Bool) {
|
||||
if primaryButtonShowing, secondaryButtonShowing {
|
||||
heightConstraint?.isActive = false
|
||||
if primaryButton == nil || secondaryButton == nil {
|
||||
removeButtons()
|
||||
setupWithTwoButtons()
|
||||
}
|
||||
} else if primaryButtonShowing {
|
||||
heightConstraint?.isActive = false
|
||||
if primaryButton == nil || secondaryButton != nil {
|
||||
removeButtons()
|
||||
setupWithPrimaryButton()
|
||||
}
|
||||
} else if secondaryButtonShowing {
|
||||
heightConstraint?.isActive = false
|
||||
if secondaryButton == nil || primaryButton != nil {
|
||||
removeButtons()
|
||||
setupWithSecondaryButton()
|
||||
}
|
||||
} else {
|
||||
removeButtons()
|
||||
if heightConstraint == nil {
|
||||
heightConstraint = heightAnchor.constraint(equalToConstant: 0)
|
||||
heightConstraint?.isActive = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON)
|
||||
setDefaultCustom()
|
||||
primaryButton?.setWithJSON(primaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData)
|
||||
secondaryButton?.setWithJSON(secondaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
// MARK: - Legacy
|
||||
public convenience init(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
self.init()
|
||||
setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
public convenience init(buttonSmall small: Bool, buttonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: AnyHashable]?) {
|
||||
self.init()
|
||||
setup(withButtonMap: buttonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
primaryButton?.setAsSmall(small)
|
||||
secondaryButton?.setAsSmall(small)
|
||||
}
|
||||
|
||||
public convenience init(buttonSmall small: Bool, enabled: Bool) {
|
||||
self.init()
|
||||
removeButtons()
|
||||
setupWithPrimaryButton()
|
||||
primaryButton?.setAsSmall(small)
|
||||
primaryButton?.isEnabled = enabled
|
||||
}
|
||||
|
||||
open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap)
|
||||
if primaryButtonMap != nil, secondaryButtonMap != nil {
|
||||
primaryButton?.setWithActionMap(primaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
secondaryButton?.setWithActionMap(secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
} else if primaryButtonMap != nil {
|
||||
primaryButton?.setWithActionMap(primaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
primaryButton?.bordered = false
|
||||
} else if secondaryButtonMap != nil {
|
||||
secondaryButton?.setWithActionMap(secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
secondaryButton?.bordered = true
|
||||
}
|
||||
}
|
||||
|
||||
open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton)
|
||||
let primaryButtonMap = buttonMap?.optionalDictionaryForKey(KeyPrimaryButton)
|
||||
setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
public func hideLeftButton() {
|
||||
guard let secondaryButton = secondaryButton, !secondaryButton.isHidden else {
|
||||
return
|
||||
}
|
||||
secondaryButton.isHidden = true
|
||||
if let primaryButton = primaryButton {
|
||||
primaryButton.removeFromSuperview()
|
||||
viewForButtons?.addSubview(primaryButton)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: primaryButton)
|
||||
}
|
||||
}
|
||||
|
||||
public func hideRightButton() {
|
||||
guard let primaryButton = primaryButton, !primaryButton.isHidden else {
|
||||
return
|
||||
}
|
||||
primaryButton.isHidden = true
|
||||
if let secondaryButton = secondaryButton {
|
||||
secondaryButton.removeFromSuperview()
|
||||
viewForButtons?.addSubview(secondaryButton)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: secondaryButton)
|
||||
}
|
||||
}
|
||||
|
||||
public func showBothButtons() {
|
||||
primaryButton?.isHidden = false
|
||||
secondaryButton?.isHidden = false
|
||||
if let primaryButton = primaryButton, let secondaryButton = secondaryButton {
|
||||
primaryButton.removeFromSuperview()
|
||||
secondaryButton.removeFromSuperview()
|
||||
setupConstraintsForViewWithButtons()
|
||||
}
|
||||
}
|
||||
|
||||
public func hideBothButtons() {
|
||||
primaryButton?.isHidden = true
|
||||
secondaryButton?.isHidden = true
|
||||
}
|
||||
|
||||
override open func horizontalAlignment() -> UIStackView.Alignment {
|
||||
|
||||
// MARK: - MVMCoreUIViewConstrainingProtocol
|
||||
open func horizontalAlignment() -> UIStackView.Alignment {
|
||||
return .center
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Deprecate
|
||||
extension TwoButtonView {
|
||||
@available(*, deprecated)
|
||||
open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) {
|
||||
setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap)
|
||||
if primaryButtonMap != nil, secondaryButtonMap != nil {
|
||||
primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
||||
secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
||||
} else if primaryButtonMap != nil {
|
||||
primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
||||
primaryButton?.bordered = false
|
||||
} else if secondaryButtonMap != nil {
|
||||
secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
||||
secondaryButton?.bordered = true
|
||||
|
||||
// MARK: - ModelMoleculeViewProtocol
|
||||
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
guard let model = molecule as? TwoButtonViewModel else { return 0 }
|
||||
return PillButton.estimatedHeight(forRow: model.primaryButton ?? model.secondaryButton, delegateObject: delegateObject)
|
||||
}
|
||||
|
||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
guard let model = model as? TwoButtonViewModel else { return }
|
||||
if let secondaryModel = model.secondaryButton {
|
||||
showSecondaryButton()
|
||||
secondaryButton.setWithModel(secondaryModel, delegateObject, additionalData)
|
||||
} else {
|
||||
hideSecondaryButton()
|
||||
}
|
||||
if let primaryModel = model.primaryButton {
|
||||
showPrimaryButton()
|
||||
primaryButton.setWithModel(primaryModel, delegateObject, additionalData)
|
||||
} else {
|
||||
hidePrimaryButton()
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) {
|
||||
let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton)
|
||||
let primaryButtonMap = buttonMap?.optionalDictionaryForKey(KeyPrimaryButton)
|
||||
setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate)
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
public convenience init(buttonSmall small: Bool, buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: AnyHashable]?, buttonDelegate: Any?) {
|
||||
self.init()
|
||||
setup(withButtonMap: buttonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate)
|
||||
primaryButton?.setAsSmall(small)
|
||||
secondaryButton?.setAsSmall(small)
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
public convenience init(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) {
|
||||
self.init()
|
||||
setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate)
|
||||
}
|
||||
}
|
||||
|
||||
extension TwoButtonView: ModelMoleculeViewProtocol {
|
||||
public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
guard let model = model as? TwoButtonViewModel else { return }
|
||||
setupUI(primaryButtonShowing: model.primaryButton != nil, secondaryButtonShowing: model.secondaryButton != nil)
|
||||
setDefaultCustom()
|
||||
primaryButton?.setWithModel(model.primaryButton, delegateObject, additionalData)
|
||||
secondaryButton?.setWithModel(model.secondaryButton, delegateObject, additionalData)
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,9 +8,40 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
public struct TwoButtonViewModel: MoleculeModelProtocol {
|
||||
public class TwoButtonViewModel: MoleculeModelProtocol {
|
||||
public static var identifier: String = "twoButtonView"
|
||||
public var backgroundColor: Color?
|
||||
public var primaryButton: ButtonModel?
|
||||
public var secondaryButton: ButtonModel?
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case primaryButton
|
||||
case secondaryButton
|
||||
}
|
||||
|
||||
public init(_ primaryButton: ButtonModel?, _ secondaryButton: ButtonModel?) {
|
||||
self.primaryButton = primaryButton
|
||||
self.secondaryButton = secondaryButton
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
primaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .primaryButton)
|
||||
secondaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .secondaryButton)
|
||||
// Default value
|
||||
if secondaryButton?.style == nil {
|
||||
secondaryButton?.style = .secondary
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(primaryButton, forKey: .primaryButton)
|
||||
try container.encodeIfPresent(secondaryButton, forKey: .secondaryButton)
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,28 +8,31 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
class AccordionListItemModel: MoleculeContainerModel, ListItemModelProtocol {
|
||||
public static var identifier: String = "accordionListItem"
|
||||
public var molecules: [ListItemModelProtocol]
|
||||
public var backgroundColor: Color?
|
||||
class AccordionListItemModel: MoleculeListItemModel {
|
||||
override public class var identifier: String {
|
||||
return "accordionListItem"
|
||||
}
|
||||
public var molecules: [ListItemModelProtocol & MoleculeModelProtocol]
|
||||
public var hideLineWhenExpanded: Bool = false
|
||||
public var hideArrow: Bool? = true
|
||||
public var line: LineModel?
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case molecules
|
||||
case backgroundColor
|
||||
case molecule
|
||||
case hideLineWhenExpanded
|
||||
case hideArrow
|
||||
case line
|
||||
}
|
||||
|
||||
public override func setDefaults() {
|
||||
super.setDefaults()
|
||||
hideArrow = true
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
molecules = try typeContainer.decodeMolecules(codingKey: .molecules) as! [ListItemModelProtocol]
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
||||
guard let molecules = try typeContainer.decodeMolecules(codingKey: .molecules) as? [ListItemModelProtocol & MoleculeModelProtocol] else {
|
||||
throw DecodingError.typeMismatch([ListItemModelProtocol & MoleculeModelProtocol].self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Casting failed"))
|
||||
}
|
||||
self.molecules = molecules
|
||||
if let hideLine = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideLineWhenExpanded) {
|
||||
hideLineWhenExpanded = hideLine
|
||||
}
|
||||
@ -41,8 +44,6 @@ class AccordionListItemModel: MoleculeContainerModel, ListItemModelProtocol {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeModels(molecules, forKey: .molecules)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(hideLineWhenExpanded, forKey: .hideLineWhenExpanded)
|
||||
try container.encodeIfPresent(line, forKey: .line)
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,9 @@
|
||||
import UIKit
|
||||
|
||||
@objcMembers public class AccordionMoleculeTableViewCell: MoleculeTableViewCell {
|
||||
var accordionListItemModel: AccordionListItemModel?
|
||||
var accordionListItemModel: AccordionListItemModel? {
|
||||
return listItemModel as? AccordionListItemModel
|
||||
}
|
||||
let accordionButton = createAccordionButton()
|
||||
|
||||
static func createAccordionButton() -> MFCustomButton {
|
||||
@ -30,10 +32,14 @@ import UIKit
|
||||
override public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||
accordionButton.isSelected = !accordionButton.isSelected
|
||||
accordionButton.setTitle(accordionButton.isSelected ? "-" : "+", for: .normal)
|
||||
guard let molecules = accordionListItemModel?.molecules else {
|
||||
guard let model = accordionListItemModel else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let json = model.toJSON(),
|
||||
let molecules = json.optionalArrayForKey("molecules") as? [[AnyHashable: Any]]
|
||||
else { return }
|
||||
|
||||
if accordionButton.isSelected {
|
||||
delegateObject?.moleculeDelegate?.addMolecules(molecules, sender: self, animation: .automatic)
|
||||
} else {
|
||||
|
||||
@ -24,8 +24,7 @@ import UIKit
|
||||
|
||||
override public func setupView() {
|
||||
super.setupView()
|
||||
|
||||
guard dropDown.superview == nil else { return }
|
||||
|
||||
addMolecule(dropDown)
|
||||
dropDown.observeDropdownChange = { [weak self] oldValue, newValue in
|
||||
|
||||
|
||||
@ -8,43 +8,31 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class DropDownListItemModel: ContainerModel, ListItemModelProtocol {
|
||||
@objcMembers public class DropDownListItemModel: ListItemModel, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "dropDownListItem"
|
||||
public var molecules: [[ListItemModelProtocol]]
|
||||
public var molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]
|
||||
public var dropDown: ItemDropdownEntryFieldModel
|
||||
public var backgroundColor: Color?
|
||||
public var line: LineModel? = LineModel(type: .none)
|
||||
public var hideArrow: Bool? = true
|
||||
|
||||
/// Defaults to set
|
||||
func setDefaults() {
|
||||
if useHorizontalMargins == nil {
|
||||
useHorizontalMargins = true
|
||||
}
|
||||
if useVerticalMargins == nil {
|
||||
useVerticalMargins = true
|
||||
}
|
||||
if topMarginPadding == nil {
|
||||
topMarginPadding = 24
|
||||
}
|
||||
if bottomMarginPadding == nil {
|
||||
bottomMarginPadding = 0
|
||||
}
|
||||
public override func setDefaults() {
|
||||
super.setDefaults()
|
||||
hideArrow = true
|
||||
line = LineModel(type: .none)
|
||||
style = "sectionFooter"
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(molecules: [[ListItemModelProtocol]], dropDown: ItemDropdownEntryFieldModel) {
|
||||
public init(molecules: [[ListItemModelProtocol & MoleculeModelProtocol]], dropDown: ItemDropdownEntryFieldModel) {
|
||||
self.molecules = molecules
|
||||
self.dropDown = dropDown
|
||||
super.init()
|
||||
setDefaults()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -55,8 +43,6 @@ import Foundation
|
||||
case moleculeName
|
||||
case molecules
|
||||
case dropDown
|
||||
case line
|
||||
case backgroundColor
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -65,16 +51,9 @@ import Foundation
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
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)
|
||||
|
||||
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)
|
||||
setDefaults()
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
@ -83,7 +62,5 @@ import Foundation
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeModels2D(molecules, forKey: .molecules)
|
||||
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
|
||||
//
|
||||
// Created by Suresh, Kamlesh on 10/3/19.
|
||||
// Copyright © 2019 Suresh, Kamlesh. All rights reserved.
|
||||
// Created by Scott Pfeil on 2/12/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
// A base class that has common list item boilerplate model stuffs.
|
||||
|
||||
import Foundation
|
||||
import MVMCore
|
||||
|
||||
@objcMembers public class ListItemModel: MoleculeContainerModel, ListItemModelProtocol {
|
||||
|
||||
public static var identifier: String = "listItem"
|
||||
@objcMembers public class ListItemModel: ContainerModel, ListItemModelProtocol {
|
||||
public var backgroundColor: Color?
|
||||
public var action: ActionModelProtocol?
|
||||
public var hideArrow: Bool?
|
||||
public var line: LineModel?
|
||||
public var style: String? = "standard"
|
||||
public var style: String?
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case action
|
||||
case hideArrow
|
||||
@ -28,23 +25,20 @@ import MVMCore
|
||||
}
|
||||
|
||||
/// Defaults to set
|
||||
func setDefaults() {
|
||||
public func setDefaults() {
|
||||
if useHorizontalMargins == nil {
|
||||
useHorizontalMargins = true
|
||||
}
|
||||
if useVerticalMargins == nil {
|
||||
useVerticalMargins = true
|
||||
}
|
||||
if topMarginPadding == nil {
|
||||
topMarginPadding = 24
|
||||
}
|
||||
if bottomMarginPadding == nil {
|
||||
bottomMarginPadding = 24
|
||||
if style == nil {
|
||||
style = "standard"
|
||||
}
|
||||
}
|
||||
|
||||
public override init(with moleculeModel: MoleculeModelProtocol) {
|
||||
super.init(with: moleculeModel)
|
||||
public override init() {
|
||||
super.init()
|
||||
setDefaults()
|
||||
}
|
||||
|
||||
@ -54,9 +48,7 @@ import MVMCore
|
||||
action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType)
|
||||
hideArrow = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideArrow)
|
||||
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
||||
if let style = try typeContainer.decodeIfPresent(String.self, forKey: .style) {
|
||||
self.style = style
|
||||
}
|
||||
style = try typeContainer.decodeIfPresent(String.self, forKey: .style)
|
||||
try super.init(from: decoder)
|
||||
setDefaults()
|
||||
}
|
||||
@ -64,7 +56,6 @@ import MVMCore
|
||||
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.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeModelIfPresent(action, forKey: .action)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ import Foundation
|
||||
public override init(with moleculeModel: MoleculeModelProtocol) {
|
||||
super.init(with: moleculeModel)
|
||||
}
|
||||
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing)
|
||||
|
||||
@ -8,14 +8,19 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
@objcMembers open class MoleculeTableViewCell: TableViewCell {
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
|
||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
guard let model = model as? ListItemModel else { return }
|
||||
|
||||
guard let model = model as? MoleculeListItemModel else { return }
|
||||
|
||||
if molecule != nil {
|
||||
(molecule as? ModelMoleculeViewProtocol)?.setWithModel(model.molecule, delegateObject, additionalData)
|
||||
|
||||
} else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(model.molecule, delegateObject, false) {
|
||||
addMolecule(moleculeView)
|
||||
}
|
||||
@ -24,28 +29,28 @@ import UIKit
|
||||
}
|
||||
|
||||
public override class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||
guard let moleculeModel = (model as? ListItemModel)?.molecule else {
|
||||
return "\(self)<>"
|
||||
}
|
||||
guard let moleculeModel = (model as? MoleculeListItemModel)?.molecule else { return "\(self)<>" }
|
||||
|
||||
let className = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type
|
||||
let moleculeName = className?.nameForReuse(moleculeModel, delegateObject) ?? moleculeModel.moleculeName ?? ""
|
||||
|
||||
return "\(self)<\(moleculeName)>"
|
||||
}
|
||||
|
||||
public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
||||
guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule),
|
||||
let theClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON) else {
|
||||
return nil
|
||||
}
|
||||
let theClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON)
|
||||
else { return nil }
|
||||
|
||||
return theClass.requiredModules?(moleculeJSON, delegateObject: delegateObject, error: error)
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
guard let moleculeModel = (molecule as? MoleculeContainerModel)?.molecule,
|
||||
let classType = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type,
|
||||
let height = classType.estimatedHeight(forRow: moleculeModel, delegateObject: delegateObject) else {
|
||||
return 80
|
||||
}
|
||||
let height = classType.estimatedHeight(forRow: moleculeModel, delegateObject: delegateObject)
|
||||
else { return 80 }
|
||||
|
||||
return max(2 * PaddingDefaultVerticalSpacing3, height)
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class StackItemModel: StackItemModelProtocol, MoleculeModelProtocol {
|
||||
@objcMembers public class StackItemModel: ContainerModel, StackItemModelProtocol, MoleculeModelProtocol {
|
||||
public static var identifier: String = "simpleStackItem"
|
||||
public var backgroundColor: Color?
|
||||
public var spacing: CGFloat?
|
||||
@ -19,4 +19,9 @@ import Foundation
|
||||
self.init()
|
||||
self.gone = gone
|
||||
}
|
||||
|
||||
public convenience init(percent: Int) {
|
||||
self.init()
|
||||
self.percent = percent
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,39 +8,36 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
public class TabsListItemModel: ContainerModel, ListItemModelProtocol {
|
||||
public class TabsListItemModel: ListItemModel, MoleculeModelProtocol {
|
||||
public static var identifier: String = "tabsListItem"
|
||||
var tabs: TabsModel
|
||||
var molecules: [[ListItemModelProtocol]]
|
||||
|
||||
public var backgroundColor: Color?
|
||||
public var hideArrow: Bool? = true
|
||||
public var line: LineModel? = LineModel(type: .standard)
|
||||
var molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case tabs
|
||||
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.molecules = molecules
|
||||
super.init()
|
||||
self.topMarginPadding = 8
|
||||
self.bottomMarginPadding = 0
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
tabs = try typeContainer.decode(TabsModel.self, forKey: .tabs)
|
||||
molecules = try typeContainer.decodeMolecules2D(codingKey: .molecules) as! [[ListItemModelProtocol]]
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
if let lineModel = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) {
|
||||
line = lineModel
|
||||
}
|
||||
molecules = try typeContainer.decodeMolecules2D(codingKey: .molecules) as! [[ListItemModelProtocol & MoleculeModelProtocol]]
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
@ -50,7 +47,5 @@ public class TabsListItemModel: ContainerModel, ListItemModelProtocol {
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(tabs, forKey: .tabs)
|
||||
try container.encodeModels2D(molecules, forKey: .molecules)
|
||||
try container.encode(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(line, forKey: .line)
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,9 @@
|
||||
import UIKit
|
||||
|
||||
@objcMembers public class TabsTableViewCell: TableViewCell {
|
||||
var tabsListItemModel: TabsListItemModel?
|
||||
var tabsListItemModel: TabsListItemModel? {
|
||||
return listItemModel as? TabsListItemModel
|
||||
}
|
||||
let tabs = TopTabbar(frame: .zero)
|
||||
var delegateObject: MVMCoreUIDelegateObject?
|
||||
var previousTabIndex = 0
|
||||
@ -17,11 +19,7 @@ import UIKit
|
||||
// MARK: - MFViewProtocol
|
||||
override public func setupView() {
|
||||
super.setupView()
|
||||
guard tabs.superview == nil else {
|
||||
return
|
||||
}
|
||||
tabs.paddingBeforeFirstTab = false
|
||||
|
||||
tabs.translatesAutoresizingMaskIntoConstraints = false
|
||||
tabs.delegate = self
|
||||
tabs.datasource = self
|
||||
@ -48,11 +46,18 @@ import UIKit
|
||||
super.reset()
|
||||
tabs.reset()
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 46
|
||||
}
|
||||
}
|
||||
|
||||
extension TabsTableViewCell: TopTabbarDelegate {
|
||||
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)
|
||||
}
|
||||
previousTabIndex = tabs.selectedIndex
|
||||
@ -60,7 +65,10 @@ extension TabsTableViewCell: TopTabbarDelegate {
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ import UIKit
|
||||
headlineBodyLink.headlineBody.styleListItem()
|
||||
addSubview(headlineBodyLink)
|
||||
addSubview(toggle)
|
||||
NSLayoutConstraint.pinSubviewsCenter(leftView: headlineBodyLink, rightView: toggle)
|
||||
NSLayoutConstraint.pinViews(leftView: headlineBodyLink, rightView: toggle, alignTop: false)
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtoco
|
||||
|
||||
@ -31,7 +31,7 @@ import UIKit
|
||||
|
||||
view.addSubview(headlineBody)
|
||||
view.addSubview(toggle)
|
||||
NSLayoutConstraint.pinSubviewsCenter(leftView: headlineBody, rightView: toggle)
|
||||
NSLayoutConstraint.pinViews(leftView: headlineBody, rightView: toggle, alignTop: false)
|
||||
}
|
||||
|
||||
// MARK:- ModelMoleculeViewProtocol
|
||||
|
||||
@ -28,7 +28,7 @@ import UIKit
|
||||
addSubview(label)
|
||||
addSubview(toggle)
|
||||
label.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical)
|
||||
NSLayoutConstraint.pinSubviewsCenter(leftView: label, rightView: toggle)
|
||||
NSLayoutConstraint.pinViews(leftView: label, rightView: toggle, alignTop: false)
|
||||
}
|
||||
|
||||
// MARK:- ModelMoleculeViewProtocol
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
import Foundation
|
||||
@objcMembers public class HeadLineBodyCaretLinkImage: Container {
|
||||
let headlineBody = HeadlineBody(frame: .zero)
|
||||
let caretButton = CaretButton(frame: .zero)
|
||||
let caretButton = CaretLink(frame: .zero)
|
||||
let backgroundImageView = MFLoadImageView(pinnedEdges: .all)
|
||||
let maxWidth: CGFloat = 350.0
|
||||
static let heightConstant: CGFloat = 320.0
|
||||
@ -66,13 +66,6 @@ import Foundation
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
backgroundImageView.setWithJSON(json?.optionalDictionaryForKey("image"), delegateObject: delegateObject, additionalData: additionalData)
|
||||
headlineBody.setWithJSON(json?.optionalDictionaryForKey("headlineBody"), delegateObject: delegateObject, additionalData: additionalData)
|
||||
caretButton.setWithJSON(json?.optionalDictionaryForKey("caretLink"), delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
headlineBody.reset()
|
||||
|
||||
@ -24,9 +24,8 @@ open class HeadlineBody: View {
|
||||
|
||||
// MARK: - Styling
|
||||
func style(with styleString: String?) {
|
||||
guard let styleString = styleString else {
|
||||
return
|
||||
}
|
||||
guard let styleString = styleString else { return }
|
||||
|
||||
switch styleString {
|
||||
case "header":
|
||||
stylePageHeader()
|
||||
@ -72,10 +71,9 @@ open class HeadlineBody: View {
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
guard subviews.count == 0 else {
|
||||
return
|
||||
}
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
guard subviews.isEmpty else { return }
|
||||
|
||||
backgroundColor = .clear
|
||||
clipsToBounds = true
|
||||
|
||||
@ -86,9 +84,9 @@ open class HeadlineBody: View {
|
||||
view.addSubview(headlineLabel)
|
||||
view.addSubview(messageLabel)
|
||||
|
||||
headlineLabel.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical)
|
||||
messageLabel.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical)
|
||||
view.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical)
|
||||
headlineLabel.setContentHuggingPriority(.required, for: .vertical)
|
||||
messageLabel.setContentHuggingPriority(.required, for: .vertical)
|
||||
view.setContentHuggingPriority(.required, for: .vertical)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Constraining
|
||||
//--------------------------------------------------
|
||||
|
||||
public func setSpacing() {
|
||||
if headlineLabel.hasText && messageLabel.hasText {
|
||||
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? {
|
||||
return 58
|
||||
}
|
||||
|
||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
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)
|
||||
|
||||
|
||||
headlineLabel.setWithModel(headlineBodyModel.headline, delegateObject, additionalData)
|
||||
messageLabel.setWithModel(headlineBodyModel.body, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
|
||||
@ -159,4 +164,3 @@ open class HeadlineBody: View {
|
||||
return 58
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@ import Foundation
|
||||
|
||||
@objcMembers public class HeadlineBodyModel: MoleculeModelProtocol {
|
||||
public static var identifier: String = "headlineBody"
|
||||
public var moleculeName: String?
|
||||
public var headline: LabelModel?
|
||||
public var body: LabelModel?
|
||||
public var style: String?
|
||||
@ -20,4 +19,3 @@ import Foundation
|
||||
self.headline = headline
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ import Foundation
|
||||
public extension MVMCoreUIMoleculeMappingObject {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
@ -22,8 +22,7 @@
|
||||
@"stack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackTemplate class]],
|
||||
@"centerMoleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackCenteredTemplate class]],
|
||||
@"list" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeListTemplate class]],
|
||||
@"threeLayer" :
|
||||
[[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[ThreeLayerTemplate class]]
|
||||
@"threeLayer" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[ThreeLayerTemplate class]]
|
||||
} mutableCopy];
|
||||
});
|
||||
return viewControllerMapping;
|
||||
|
||||
@ -23,8 +23,8 @@ public protocol MoleculeDelegateProtocol {
|
||||
func removeMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation)
|
||||
|
||||
//optional
|
||||
func addMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation)
|
||||
func removeMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation)
|
||||
func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation)
|
||||
func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation)
|
||||
}
|
||||
|
||||
extension MoleculeDelegateProtocol {
|
||||
@ -40,11 +40,11 @@ extension MoleculeDelegateProtocol {
|
||||
// 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
|
||||
}
|
||||
|
||||
public func removeMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||
public func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,19 +18,19 @@ import Foundation
|
||||
|
||||
// Label
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Label.self, viewModelClass: LabelModel.self)
|
||||
//need to move labelattributemodel to different method
|
||||
ModelRegistry.register(LabelAttributeFontModel.self)
|
||||
ModelRegistry.register(LabelAttributeColorModel.self)
|
||||
//ModelRegistry.register(LabelAttributeImageModel.self) // We need to separate the registry by types due to collisions...
|
||||
ModelRegistry.register(LabelAttributeUnderlineModel.self)
|
||||
ModelRegistry.register(LabelAttributeStrikeThroughModel.self)
|
||||
ModelRegistry.register(LabelAttributeActionModel.self)
|
||||
// need to move labelattributemodel to different method
|
||||
try? ModelRegistry.register(LabelAttributeFontModel.self)
|
||||
try? ModelRegistry.register(LabelAttributeColorModel.self)
|
||||
try? ModelRegistry.register(LabelAttributeImageModel.self) // We need to separate the registry by types due to collisions...
|
||||
try? ModelRegistry.register(LabelAttributeUnderlineModel.self)
|
||||
try? ModelRegistry.register(LabelAttributeStrikeThroughModel.self)
|
||||
try? ModelRegistry.register(LabelAttributeActionModel.self)
|
||||
|
||||
// Buttons
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TwoButtonView.self, viewModelClass: TwoButtonViewModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Link.self, viewModelClass: LinkModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretButton.self, viewModelClass: CaretLinkModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretLink.self, viewModelClass: CaretLinkModel.self)
|
||||
|
||||
// Entry Field
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TextEntryField.self, viewModelClass: TextEntryFieldModel.self)
|
||||
@ -40,7 +40,6 @@ import Foundation
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: DateDropdownEntryField.self, viewModelClass: DateDropdownEntryFieldModel.self)
|
||||
|
||||
// Other Atoms
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Label.self, viewModelClass: LabelModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretView.self, viewModelClass: CaretViewModel.self)
|
||||
@ -55,6 +54,8 @@ import Foundation
|
||||
// Horizontal Combination Molecules
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListThreeColumnPlanDataDivider.self, viewModelClass: ListThreeColumnPlanDataDividerModel.self)
|
||||
|
||||
|
||||
// Vertical Combination Molecules
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self)
|
||||
@ -71,9 +72,10 @@ import Foundation
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyToggle.self, viewModelClass: HeadlineBodyToggleModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyLinkToggle.self, viewModelClass: HeadlineBodyLinkToggleModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ActionDetailWithImage.self, viewModelClass: ActionDetailWithImageModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListLeftVariableIconWithRightCaret.self, viewModelClass: ListLeftVariableIconWithRightCaretModel.self)
|
||||
|
||||
// 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: AccordionMoleculeTableViewCell.self, viewModelClass: AccordionListItemModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TabsTableViewCell.self, viewModelClass: TabsListItemModel.self)
|
||||
@ -105,6 +107,6 @@ import Foundation
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(MVMCoreUIPageControl.self, forKey: "barsPager" as NSString)
|
||||
|
||||
// TODO: Need View
|
||||
ModelRegistry.register(TabsModel.self)
|
||||
try? ModelRegistry.register(TabsModel.self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,10 @@
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class ListPageTemplateModel: TemplateModelProtocol {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "list"
|
||||
|
||||
public var pageType: String
|
||||
@ -17,16 +20,24 @@ import Foundation
|
||||
public var isAtomicTabs: Bool?
|
||||
|
||||
public var header: MoleculeModelProtocol?
|
||||
public var molecules: [ListItemModelProtocol]?
|
||||
public var molecules: [ListItemModelProtocol & MoleculeModelProtocol]?
|
||||
public var footer: MoleculeModelProtocol?
|
||||
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.screenHeading = screenHeading
|
||||
self.molecules = molecules
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case pageType
|
||||
@ -38,11 +49,15 @@ import Foundation
|
||||
case isAtomicTabs
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
pageType = try typeContainer.decode(String.self, forKey: .pageType)
|
||||
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)
|
||||
header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header)
|
||||
footer = try typeContainer.decodeMoleculeIfPresent(codingKey: .footer)
|
||||
|
||||
@ -9,52 +9,67 @@
|
||||
import UIKit
|
||||
|
||||
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?
|
||||
|
||||
public var templateModel: ListPageTemplateModel?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Computed Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@objc public override func parsePageJSON() throws {
|
||||
try parseTemplateJSON()
|
||||
}
|
||||
|
||||
open override var loadObject: MVMCoreLoadObject? {
|
||||
didSet {
|
||||
if loadObject != oldValue {
|
||||
updateRequiredModules()
|
||||
observer?.invalidate()
|
||||
if let newObject = loadObject {
|
||||
observer = newObject.observe(\MVMCoreLoadObject.pageJSON, options: [.old, .new]) { [weak self] (object, change) in
|
||||
self?.updateRequiredModules()
|
||||
}
|
||||
guard loadObject != oldValue else { return }
|
||||
|
||||
updateRequiredModules()
|
||||
observer?.invalidate()
|
||||
if let newObject = loadObject {
|
||||
observer = newObject.observe(\MVMCoreLoadObject.pageJSON, options: [.old, .new]) { [weak self] object, change in
|
||||
self?.updateRequiredModules()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func viewForTop() -> UIView {
|
||||
guard let headerModel = templateModel?.header,
|
||||
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(headerModel, delegateObject() as? MVMCoreUIDelegateObject, false) else {
|
||||
return super.viewForTop()
|
||||
}
|
||||
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(headerModel, delegateObject() as? MVMCoreUIDelegateObject, false)
|
||||
else { return super.viewForTop() }
|
||||
|
||||
// Temporary, Default the horizontal padding
|
||||
if var container = templateModel?.header as? ContainerModelProtocol, container.useHorizontalMargins == nil {
|
||||
container.useHorizontalMargins = true
|
||||
}
|
||||
|
||||
return molecule
|
||||
}
|
||||
|
||||
override open func viewForBottom() -> UIView {
|
||||
guard let footerModel = templateModel?.footer,
|
||||
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(footerModel, delegateObject() as? MVMCoreUIDelegateObject, false) else {
|
||||
return super.viewForBottom()
|
||||
}
|
||||
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(footerModel, delegateObject() as? MVMCoreUIDelegateObject, false)
|
||||
else { return super.viewForBottom() }
|
||||
|
||||
return molecule
|
||||
}
|
||||
|
||||
open override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
|
||||
|
||||
guard super.shouldFinishProcessingLoad(loadObject, error: error) else { return false }
|
||||
|
||||
// This template requires atleast one of the three layers.
|
||||
if templateModel?.header == nil,
|
||||
templateModel?.molecules?.count ?? 0 == 0,
|
||||
@ -72,7 +87,10 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
registerWithTable()
|
||||
}
|
||||
|
||||
// MARK: - table
|
||||
//--------------------------------------------------
|
||||
// MARK: - Table View
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func registerWithTable() {
|
||||
super.registerWithTable()
|
||||
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 {
|
||||
guard let moleculeInfo = moleculesInfo?[indexPath.row],
|
||||
let estimatedHeight = (moleculeInfo.class as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(forRow: moleculeInfo.molecule, delegateObject: delegateObject() as? MVMCoreUIDelegateObject) else {
|
||||
return 0
|
||||
}
|
||||
let estimatedHeight = (moleculeInfo.class as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(forRow: moleculeInfo.molecule, delegateObject: delegateObject() as? MVMCoreUIDelegateObject)
|
||||
else { return 0 }
|
||||
|
||||
return estimatedHeight
|
||||
}
|
||||
|
||||
@ -95,18 +113,22 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
}
|
||||
|
||||
open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
|
||||
guard let moleculeInfo = moleculesInfo?[indexPath.row],
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier) else {
|
||||
return UITableViewCell()
|
||||
}
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier)
|
||||
else { return UITableViewCell() }
|
||||
|
||||
let delegate = delegateObject() as? MVMCoreUIDelegateObject
|
||||
let moleculeCell = cell as? MVMCoreUIMoleculeViewProtocol
|
||||
moleculeCell?.reset?()
|
||||
|
||||
if let protocolCell = cell as? MoleculeListCellProtocol {
|
||||
protocolCell.setLines(with: templateModel?.line, delegateObject: delegate, additionalData: nil, indexPath: indexPath)
|
||||
}
|
||||
|
||||
(moleculeCell as? ModelMoleculeViewProtocol)?.setWithModel(moleculeInfo.molecule, delegate, nil)
|
||||
moleculeCell?.updateView(tableView.bounds.width)
|
||||
moleculeCell?.updateView(tableView.bounds.width)
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
@ -118,16 +140,18 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
}
|
||||
|
||||
open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
|
||||
if let cell = tableView.cellForRow(at: indexPath) as? MoleculeListCellProtocol {
|
||||
cell.didSelectCell(at: indexPath, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - cache handling
|
||||
//--------------------------------------------------
|
||||
// MARK: - Cache Handling
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func pageTypesToListenFor() -> [Any]? {
|
||||
guard let pageType = self.pageType else {
|
||||
return super.pageTypesToListenFor()
|
||||
}
|
||||
guard let pageType = self.pageType else { return super.pageTypesToListenFor() }
|
||||
return [pageType]
|
||||
}
|
||||
|
||||
@ -135,8 +159,12 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
return loadObject?.requestParameters?.modules
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MoleculeDelegateProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) {
|
||||
|
||||
if let tableView = tableView {
|
||||
let point = molecule.convert(molecule.bounds.origin, to: tableView)
|
||||
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) {
|
||||
|
||||
var tmpMolecules = [ListItemModelProtocol]()
|
||||
var tmpMolecules = [ListItemModelProtocol & MoleculeModelProtocol]()
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -159,6 +187,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
DispatchQueue.main.async {
|
||||
guard let indexPath = self.tableView?.indexPath(for: sender) else { return }
|
||||
var indexPaths: [IndexPath] = []
|
||||
|
||||
for molecule in tmpMolecules {
|
||||
if let info = self.getMoleculeInfo(with: molecule) {
|
||||
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
|
||||
@ -167,6 +196,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
indexPaths.append(IndexPath(row: index, section: 0))
|
||||
}
|
||||
}
|
||||
|
||||
self.tableView?.insertRows(at: indexPaths, with: animation)
|
||||
self.updateViewConstraints()
|
||||
self.view.layoutIfNeeded()
|
||||
@ -175,34 +205,39 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
|
||||
public override func removeMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||
|
||||
var tmpMolecules = [ListItemModelProtocol]()
|
||||
var tmpMolecules = [ListItemModelProtocol & MoleculeModelProtocol]()
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
var indexPaths: [IndexPath] = []
|
||||
|
||||
//TODO: cehck for molecule protocola eqality
|
||||
|
||||
for molecule in tmpMolecules {
|
||||
if let removeIndex = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in
|
||||
return molecule.toJSONString() == moleculeInfo.molecule.toJSONString()
|
||||
}) {
|
||||
if let removeIndex = moleculesInfo?.firstIndex(where: { molecule.toJSON() == $0.molecule.toJSON() }) {
|
||||
|
||||
moleculesInfo?.remove(at: removeIndex)
|
||||
indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0))
|
||||
}
|
||||
}
|
||||
self.tableView?.deleteRows(at: indexPaths, with: animation)
|
||||
self.updateViewConstraints()
|
||||
self.view.layoutIfNeeded()
|
||||
|
||||
tableView?.deleteRows(at: indexPaths, with: animation)
|
||||
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.
|
||||
DispatchQueue.main.async {
|
||||
guard let indexPath = self.tableView?.indexPath(for: sender) else { return }
|
||||
var indexPaths: [IndexPath] = []
|
||||
|
||||
for molecule in molecules {
|
||||
if let info = self.getMoleculeInfo(with: molecule) {
|
||||
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
|
||||
@ -211,42 +246,50 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
indexPaths.append(IndexPath(row: index, section: 0))
|
||||
}
|
||||
}
|
||||
|
||||
self.tableView?.insertRows(at: indexPaths, with: animation)
|
||||
self.updateViewConstraints()
|
||||
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] = []
|
||||
//TODO: cehck for molecule protocola eqality
|
||||
|
||||
for molecule in molecules {
|
||||
if let removeIndex = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in
|
||||
return molecule.toJSONString() == moleculeInfo.molecule.toJSONString()
|
||||
}) {
|
||||
if let removeIndex = moleculesInfo?.firstIndex(where: { molecule.toJSON() == $0.molecule.toJSON() }) {
|
||||
moleculesInfo?.remove(at: removeIndex)
|
||||
indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0))
|
||||
}
|
||||
}
|
||||
self.tableView?.deleteRows(at: indexPaths, with: animation)
|
||||
self.updateViewConstraints()
|
||||
self.view.layoutIfNeeded()
|
||||
|
||||
tableView?.deleteRows(at: indexPaths, with: animation)
|
||||
updateViewConstraints()
|
||||
view.layoutIfNeeded()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Convenience
|
||||
//--------------------------------------------------
|
||||
|
||||
/// 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,
|
||||
let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(listItem),
|
||||
let moleculeName = (moleculeClass as? ModelMoleculeViewProtocol.Type)?.nameForReuse(listItem, delegateObject() as? MVMCoreUIDelegateObject) ?? listItem.moleculeName else {
|
||||
return nil
|
||||
}
|
||||
let moleculeName = (moleculeClass as? ModelMoleculeViewProtocol.Type)?.nameForReuse(listItem, delegateObject() as? MVMCoreUIDelegateObject) ?? listItem.moleculeName
|
||||
else { return nil }
|
||||
|
||||
return (moleculeName, moleculeClass, listItem)
|
||||
}
|
||||
|
||||
/// Sets up the molecule list and ensures no errors loading all content.
|
||||
func getMoleculeInfoList() -> [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)]? {
|
||||
var moleculeList: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)] = []
|
||||
func getMoleculeInfoList() -> [(identifier: String, class: AnyClass, molecule: (ListItemModelProtocol & MoleculeModelProtocol))]? {
|
||||
|
||||
var moleculeList: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol & MoleculeModelProtocol)] = []
|
||||
|
||||
if let molecules = templateModel?.molecules {
|
||||
for molecule in molecules {
|
||||
if let info = getMoleculeInfo(with: molecule) {
|
||||
@ -254,6 +297,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return moleculeList.count > 0 ? moleculeList : nil
|
||||
}
|
||||
|
||||
@ -271,15 +315,19 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
|
||||
/// Gets modules required by the loadObject.pageJSON.
|
||||
open func requiredModules() -> [Any]? {
|
||||
|
||||
let modules: NSMutableArray = []
|
||||
let delegate = delegateObject() as? MVMCoreUIDelegateObject
|
||||
|
||||
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)
|
||||
|
||||
if let molecules = loadObject?.pageJSON?.optionalArrayForKey(KeyMolecules) as? [[AnyHashable: Any]] {
|
||||
for molecule in molecules {
|
||||
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: molecule, delegateObject: delegate, moduleList: modules, errorList: nil)
|
||||
}
|
||||
}
|
||||
|
||||
return modules as? [Any]
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ public protocol TemplateProtocol: class {
|
||||
}
|
||||
|
||||
public extension TemplateProtocol where Self: MFViewController {
|
||||
|
||||
func parseTemplateJSON() throws {
|
||||
guard let pageJSON = self.loadObject?.pageJSON else { return }
|
||||
let data = try JSONSerialization.data(withJSONObject: pageJSON)
|
||||
|
||||
@ -41,7 +41,7 @@ import Foundation
|
||||
screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading)
|
||||
isAtomicTabs = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAtomicTabs)
|
||||
header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header)
|
||||
header = try typeContainer.decodeMoleculeIfPresent(codingKey: .middle)
|
||||
middle = try typeContainer.decodeMoleculeIfPresent(codingKey: .middle)
|
||||
footer = try typeContainer.decodeMoleculeIfPresent(codingKey: .footer)
|
||||
}
|
||||
|
||||
|
||||
@ -30,16 +30,16 @@
|
||||
- (nullable instancetype)initWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate viewToLayout:(nonnull UIView *)viewTolayout;
|
||||
|
||||
// Used primarily for when button presses will expand or collapse. (Short view button will need to be set manually)
|
||||
- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate viewToLayout:(nonnull UIView *)viewTolayout;
|
||||
- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate viewToLayout:(nonnull UIView *)viewTolayout;
|
||||
- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate viewToLayout:(nonnull UIView *)viewTolayout;
|
||||
- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate viewToLayout:(nonnull UIView *)viewTolayout;
|
||||
|
||||
// Used when button uses standard action map.
|
||||
- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate viewToLayout:(nonnull UIView *)viewTolayout;
|
||||
- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate viewToLayout:(nonnull UIView *)viewTolayout;
|
||||
|
||||
// Convenience change functions
|
||||
- (void)setTopMessage:(nullable NSString *)topMessage;
|
||||
- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData;
|
||||
- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler;
|
||||
- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData;
|
||||
- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler;
|
||||
|
||||
// Setters for making buttons expand and collapse the cell.
|
||||
- (void)setButtonPressToExpand;
|
||||
|
||||
@ -41,10 +41,10 @@
|
||||
- (void)setupTopAlertWithButton:(MVMCoreUITopAlertMainView *)topAlertWithButton;
|
||||
|
||||
// Sets up the whole view without setting button action.
|
||||
- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle;
|
||||
- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle;
|
||||
|
||||
// Sets up the whole view while setting button action.
|
||||
- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData;
|
||||
- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData;
|
||||
|
||||
@end
|
||||
|
||||
@ -97,14 +97,8 @@
|
||||
[self setupTopAlertWithButton:topAlertWithButton];
|
||||
|
||||
// Sets the color
|
||||
if (topAlertObject.backgroundColor) {
|
||||
self.backgroundColor = topAlertObject.backgroundColor;
|
||||
} else {
|
||||
self.backgroundColor = [[MVMCoreUITopAlertView sharedGlobal] getBackgroundColorForType:topAlertObject.type];
|
||||
}
|
||||
if (topAlertObject.textColor) {
|
||||
self.shortView.label.textColor = topAlertObject.textColor;
|
||||
}
|
||||
self.shortView.label.textColor = topAlertObject.textColor ?: [[MVMCoreUITopAlertView sharedGlobal] getContentColorForType:topAlertObject.type];
|
||||
self.backgroundColor = topAlertObject.backgroundColor ?: [[MVMCoreUITopAlertView sharedGlobal] getBackgroundColorForType:topAlertObject.type];
|
||||
|
||||
if (topAlertWithButton.label.text.length > 0) {
|
||||
[self expand:NO];
|
||||
@ -112,8 +106,10 @@
|
||||
} else {
|
||||
|
||||
// Old style, has no top alert and main view is limited.
|
||||
self.backgroundColor = [[MVMCoreUITopAlertView sharedGlobal] getBackgroundColorForType:topAlertObject.type]; [self setupTopMessage:nil];
|
||||
MVMCoreUITopAlertMainView *topAlertWithButton = [[MVMCoreUITopAlertMainView alloc] initWithColor:self.backgroundColor message:topAlertObject.message subMessage:nil closeButton:YES animationDelegate:animationDelegate];
|
||||
self.backgroundColor = [[MVMCoreUITopAlertView sharedGlobal] getBackgroundColorForType:topAlertObject.type];
|
||||
UIColor *contentColor = [[MVMCoreUITopAlertView sharedGlobal] getContentColorForType:topAlertObject.type];
|
||||
[self setupTopMessage:nil];
|
||||
MVMCoreUITopAlertMainView *topAlertWithButton = [[MVMCoreUITopAlertMainView alloc] initWithColor:self.backgroundColor contentColor:contentColor message:topAlertObject.message subMessage:nil closeButton:YES animationDelegate:animationDelegate];
|
||||
[self setupTopAlertWithButton:topAlertWithButton];
|
||||
[self expand:NO];
|
||||
}
|
||||
@ -121,29 +117,29 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate viewToLayout:(nonnull UIView *)viewTolayout {
|
||||
- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate viewToLayout:(nonnull UIView *)viewTolayout {
|
||||
if ([self init]) {
|
||||
self.animationDelegate = animationDelegate;
|
||||
self.viewToLayout = viewTolayout;
|
||||
[self setupViewWithTopMessage:topMessage message:message subMessage:nil buttonTitle:buttonTitle];
|
||||
[self setupViewWithTopMessage:topMessage message:message subMessage:nil contentColor:contentColor buttonTitle:buttonTitle];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate viewToLayout:(nonnull UIView *)viewTolayout {
|
||||
- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate viewToLayout:(nonnull UIView *)viewTolayout {
|
||||
if ([self init]) {
|
||||
self.animationDelegate = animationDelegate;
|
||||
self.viewToLayout = viewTolayout;
|
||||
[self setupViewWithTopMessage:topMessage message:message subMessage:subMessage buttonTitle:buttonTitle];
|
||||
[self setupViewWithTopMessage:topMessage message:message subMessage:subMessage contentColor:contentColor buttonTitle:buttonTitle];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate viewToLayout:(nonnull UIView *)viewTolayout {
|
||||
- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate viewToLayout:(nonnull UIView *)viewTolayout {
|
||||
if ([self init]) {
|
||||
self.animationDelegate = animationDelegate;
|
||||
self.viewToLayout = viewTolayout;
|
||||
[self setupViewWithTopMessage:topMessage message:message subMessage:subMessage actionMap:actionMap additionalData:additionalData];
|
||||
[self setupViewWithTopMessage:topMessage message:message subMessage:subMessage contentColor:contentColor actionMap:actionMap additionalData:additionalData];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -174,19 +170,19 @@
|
||||
[NSLayoutConstraint constraintPinSubview:topAlertWithButton pinTop:NO topConstant:0 pinBottom:YES bottomConstant:0 pinLeft:YES leftConstant:0 pinRight:YES rightConstant:0];
|
||||
}
|
||||
|
||||
- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle {
|
||||
- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle {
|
||||
|
||||
[self setupTopMessage:topMessage];
|
||||
|
||||
MVMCoreUITopAlertMainView *topAlertWithButton = [[MVMCoreUITopAlertMainView alloc] initWithColor:[UIColor clearColor] message:message subMessage:subMessage buttonTitle:buttonTitle userActionHandler:nil];
|
||||
MVMCoreUITopAlertMainView *topAlertWithButton = [[MVMCoreUITopAlertMainView alloc] initWithColor:[UIColor clearColor] contentColor:contentColor message:message subMessage:subMessage buttonTitle:buttonTitle userActionHandler:nil];
|
||||
[self setupTopAlertWithButton:topAlertWithButton];
|
||||
}
|
||||
|
||||
- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData {
|
||||
- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData {
|
||||
|
||||
[self setupTopMessage:topMessage];
|
||||
|
||||
MVMCoreUITopAlertMainView *topAlertWithButton = [[MVMCoreUITopAlertMainView alloc] initWithColor:[UIColor clearColor] message:message subMessage:subMessage actionMap:actionMap additionalData:additionalData];
|
||||
MVMCoreUITopAlertMainView *topAlertWithButton = [[MVMCoreUITopAlertMainView alloc] initWithColor:[UIColor clearColor] contentColor:contentColor message:message subMessage:subMessage actionMap:actionMap additionalData:additionalData];
|
||||
[self setupTopAlertWithButton:topAlertWithButton];
|
||||
}
|
||||
|
||||
@ -204,17 +200,17 @@
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData {
|
||||
- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData {
|
||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
||||
[self setTopMessage:topMessage];
|
||||
[self.buttonView setupWithMessage:message subMessage:subMessage actionMap:actionMap additionalData:additionalData];
|
||||
[self.buttonView setupWithMessage:message subMessage:subMessage color:contentColor actionMap:actionMap additionalData:additionalData];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler {
|
||||
- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler {
|
||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
||||
[self setTopMessage:topMessage];
|
||||
[self.buttonView setupWithMessage:message subMessage:subMessage buttonTitle:buttonTitle userActionHandler:userActionHandler];
|
||||
[self.buttonView setupWithMessage:message subMessage:subMessage color:contentColor buttonTitle:buttonTitle userActionHandler:userActionHandler];
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
@ -22,16 +22,16 @@
|
||||
|
||||
// Standard
|
||||
- (nullable instancetype)initWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate;
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate;
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nullable UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate;
|
||||
|
||||
// inits with images
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate;
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate;
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nullable UIColor *)contentColor imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate;
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nullable UIColor *)contentColor imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate;
|
||||
|
||||
|
||||
// Setters for label and button.
|
||||
- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData;
|
||||
- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler;
|
||||
- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage color:(nullable UIColor *)color actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData;
|
||||
- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage color:(nullable UIColor *)color buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler;
|
||||
|
||||
// Setters for button.
|
||||
- (void)setupButtonWithActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData;
|
||||
@ -40,13 +40,13 @@
|
||||
#pragma mark - legacy inits
|
||||
|
||||
// Legacy init: inits with a label and button, no close button or icon.
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData;
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nonnull UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData;
|
||||
|
||||
// Legacy init: inits with a label and possible icon and close button. No main button.
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate;
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nonnull UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate;
|
||||
|
||||
// Legacy init: inits with a label and button, no close button or icon. If passing in a block to use for the button, the top alert delegate button functions will not be called.
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler;
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nonnull UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@ -60,52 +60,49 @@
|
||||
|
||||
- (nullable instancetype)initWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate {
|
||||
if ([self init]) {
|
||||
if (topAlertObject.backgroundColor) {
|
||||
self.backgroundColor = topAlertObject.backgroundColor;
|
||||
} else {
|
||||
self.backgroundColor = [[MVMCoreUITopAlertView sharedGlobal] getBackgroundColorForType:topAlertObject.type];
|
||||
}
|
||||
UIColor *contentColor = topAlertObject.textColor ?: [[MVMCoreUITopAlertView sharedGlobal] getContentColorForType:topAlertObject.type];
|
||||
self.backgroundColor = topAlertObject.backgroundColor ?: [[MVMCoreUITopAlertView sharedGlobal] getBackgroundColorForType:topAlertObject.type];
|
||||
[self setupViewWithLabelAndImage:topAlertObject.imageNameOrURL topImage:topAlertObject.aboveTextImageString];
|
||||
[self setupCloseButton:topAlertObject.useCloseButton animationDelegate:animationDelegate];
|
||||
[self setupWithMessage:topAlertObject.title subMessage:topAlertObject.message color:topAlertObject.textColor actionMap:topAlertObject.buttonMap additionalData:topAlertObject.additionalData];
|
||||
[self setupWithMessage:topAlertObject.title subMessage:topAlertObject.message color:contentColor actionMap:topAlertObject.buttonMap additionalData:topAlertObject.additionalData];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate {
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nullable UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate {
|
||||
|
||||
// Handles all scenarios.
|
||||
if ([self init]) {
|
||||
self.backgroundColor = color;
|
||||
[self setupViewWithLabelAndImage:nil topImage:nil];
|
||||
[self setupCloseButton:closeButton animationDelegate:animationDelegate];
|
||||
[self setupWithMessage:message subMessage:subMessage actionMap:actionMap additionalData:additionalData];
|
||||
[self setupWithMessage:message subMessage:subMessage color:contentColor actionMap:actionMap additionalData:additionalData];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - inits with images
|
||||
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate {
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nullable UIColor *)contentColor imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate {
|
||||
|
||||
// Handles all scenarios.
|
||||
if ([self init]) {
|
||||
self.backgroundColor = color;
|
||||
[self setupViewWithLabelAndImage:imageURL topImage:nil];
|
||||
[self setupCloseButton:closeButton animationDelegate:animationDelegate];
|
||||
[self setupWithMessage:message subMessage:subMessage actionMap:actionMap additionalData:additionalData];
|
||||
[self setupWithMessage:message subMessage:subMessage color:contentColor actionMap:actionMap additionalData:additionalData];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate {
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nullable UIColor *)contentColor imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate {
|
||||
|
||||
// No main button.
|
||||
if ([self init]) {
|
||||
self.backgroundColor = color;
|
||||
[self setupViewWithLabelAndImage:imageURL topImage:nil];
|
||||
[self setupCloseButton:closeButton animationDelegate:animationDelegate];
|
||||
[self setupWithMessage:message subMessage:subMessage buttonTitle:nil userActionHandler:NULL];
|
||||
[self setupWithMessage:message subMessage:subMessage color:contentColor buttonTitle:nil userActionHandler:NULL];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -173,7 +170,7 @@
|
||||
|
||||
if (closeButton && !self.closeButton) {
|
||||
self.closeButton = [self addCloseButtonWithAnimationDelegate:animationDelegate];
|
||||
[self.closeButton setTintColor:self.contentColor ?:[UIColor whiteColor]];
|
||||
[self.closeButton setTintColor:self.contentColor ?: [UIColor whiteColor]];
|
||||
} else if (!closeButton && self.closeButton) {
|
||||
[self.closeButton removeFromSuperview];
|
||||
self.closeButton = nil;
|
||||
@ -241,17 +238,19 @@
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData {
|
||||
[self setupWithMessage:message subMessage:subMessage color:nil actionMap:actionMap additionalData:additionalData];
|
||||
}
|
||||
|
||||
- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler {
|
||||
- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage color:(nullable UIColor *)color buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler {
|
||||
self.message = message;
|
||||
self.subMessage = subMessage;
|
||||
self.contentColor = color;
|
||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
||||
|
||||
// Sets the string
|
||||
self.label.attributedText = [MVMCoreUITopAlertBaseView getStringForMessage:message subMessage:subMessage color:nil];
|
||||
self.label.attributedText = [MVMCoreUITopAlertBaseView getStringForMessage:message subMessage:subMessage color:color];
|
||||
|
||||
// Sets the color
|
||||
if (color) {
|
||||
[self.closeButton setTintColor:color];
|
||||
}
|
||||
|
||||
// Sets the button
|
||||
[self setupButtonWithButtonTitle:buttonTitle userActionHandler:userActionHandler];
|
||||
@ -284,36 +283,36 @@
|
||||
|
||||
#pragma mark - legacy inits
|
||||
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData {
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nonnull UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData {
|
||||
|
||||
// No icon or close button.
|
||||
if ([self init]) {
|
||||
self.backgroundColor = color;
|
||||
[self setupViewWithLabelAndImage:nil topImage:nil];
|
||||
[self setupWithMessage:message subMessage:subMessage actionMap:actionMap additionalData:additionalData];
|
||||
[self setupWithMessage:message subMessage:subMessage color:contentColor actionMap:actionMap additionalData:additionalData];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate {
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nonnull UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate {
|
||||
|
||||
// No main button.
|
||||
if ([self init]) {
|
||||
self.backgroundColor = color;
|
||||
[self setupViewWithLabelAndImage:nil topImage:nil];
|
||||
[self setupWithMessage:message subMessage:subMessage color:contentColor buttonTitle:nil userActionHandler:NULL];
|
||||
[self setupCloseButton:closeButton animationDelegate:animationDelegate];
|
||||
[self setupWithMessage:message subMessage:subMessage buttonTitle:nil userActionHandler:NULL];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler {
|
||||
- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nonnull UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler {
|
||||
|
||||
// No icon or close button. Custom button action.
|
||||
if ([self init]) {
|
||||
self.backgroundColor = color;
|
||||
[self setupViewWithLabelAndImage:nil topImage:nil];
|
||||
[self setupWithMessage:message subMessage:subMessage buttonTitle:buttonTitle userActionHandler:userActionHandler];
|
||||
[self setupWithMessage:message subMessage:subMessage color:contentColor buttonTitle:buttonTitle userActionHandler:userActionHandler];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -47,9 +47,12 @@
|
||||
// Can be subclassed for custom views.
|
||||
- (nonnull MVMCoreUITopAlertBaseView *)topAlertViewForTopAlertObject:(nullable MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nonnull id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate statusBarColor:(UIColor *_Nullable *_Nullable)statusBarColor;
|
||||
|
||||
// Get the background color based on the type
|
||||
/// Get the background color based on the type
|
||||
- (nonnull UIColor *)getBackgroundColorForType:(nullable NSString *)type;
|
||||
|
||||
/// Get the content color based on the type
|
||||
- (nonnull UIColor *)getContentColorForType:(nullable NSString *)type;
|
||||
|
||||
// Set the status bar color. Used for updating the status bar when the view changes.
|
||||
- (void)setStatusBarColor:(nullable UIColor *)statusBarColor statusBarStyle:(UIStatusBarStyle)style;
|
||||
|
||||
|
||||
@ -108,12 +108,20 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed.";
|
||||
|
||||
- (nonnull UIColor *)getBackgroundColorForType:(nullable NSString *)type {
|
||||
if ([type isEqualToString:ValueTypeError]) {
|
||||
return [UIColor mfPumpkinColor];
|
||||
return [UIColor mvmOrange];
|
||||
} else {
|
||||
return [UIColor mfShamrock];
|
||||
}
|
||||
}
|
||||
|
||||
- (nonnull UIColor *)getContentColorForType:(nullable NSString *)type {
|
||||
if ([type isEqualToString:ValueTypeError]) {
|
||||
return [UIColor blackColor];
|
||||
} else {
|
||||
return [UIColor whiteColor];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showWithTopAlertObject:(nullable MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nonnull id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate completionHandler:(void (^ __nullable)(BOOL finished))completionHandler {
|
||||
|
||||
self.animationDelegate = animationDelegate;
|
||||
@ -126,7 +134,8 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed.";
|
||||
MVMCoreUITopAlertBaseView *view = [self topAlertViewForTopAlertObject:topAlertObject animationDelegate:animationDelegate statusBarColor:&statusBarColor];
|
||||
if (!statusBarColor) {
|
||||
statusBarColor = [UIColor whiteColor];
|
||||
}
|
||||
}
|
||||
#warning This logic is incomplete, it is possible to show the wrong status bar color here if the background is yellow or pumpkin.
|
||||
UIStatusBarStyle statusBarStyle = statusBarColor == [UIColor whiteColor] ? UIStatusBarStyleDefault : UIStatusBarStyleLightContent;
|
||||
[self setStatusBarColor:statusBarColor statusBarStyle:statusBarStyle];
|
||||
[self showAlertView:view topAlertObject:topAlertObject completionHandler:completionHandler];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user