Merge branch 'develop' into feature/tags_items_view

* develop: (24 commits)
  changes after discuss with Ryan
  code simplification
  update to match documentation
  fix return type
  remove excess internal
  comment
  comment
  ordering of left buttons
  fixes for navigation item setter
  fixes for decoding
  Move enable able from button protocol added navigation button atoms and protocol. Changed the way split handles additional buttons
  remove panel from navigation setting.
  corrections made
  disabled and init
  21042(iOS - List - Left Variable - Icon - With Right Caret - Body Text) initial commit. Added model and molecule class files.
  Code clean as per review comment.
  inversion colors
  latest inversion
  changes for inversion
  current state
  ...
This commit is contained in:
Damodaram 2020-05-29 15:59:20 +05:30
commit a90758e73a
48 changed files with 1071 additions and 365 deletions

View File

@ -183,6 +183,8 @@
94CA227D24058534002D6750 /* VerizonNHGeDS-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227924058533002D6750 /* VerizonNHGeDS-Regular.otf */; };
94CA227E24058534002D6750 /* VerizonNHGeDS-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227A24058533002D6750 /* VerizonNHGeDS-Bold.otf */; };
94F6516D2437954100631BF9 /* Tabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94F6516C2437954100631BF9 /* Tabs.swift */; };
AA0A257824766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA0A257724766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift */; };
AA0A257A24766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA0A257924766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift */; };
AA104B1A24474A66004D2810 /* HeadersH2Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */; };
AA104B1C24474A76004D2810 /* HeadersH2ButtonsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104B1B24474A76004D2810 /* HeadersH2ButtonsModel.swift */; };
AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA11A41E23F15D3100D7962F /* ListRightVariablePayments.swift */; };
@ -199,6 +201,8 @@
AA617AB22453012400910B8F /* ListDeviceComplexLinkSmallModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA617AB12453012400910B8F /* ListDeviceComplexLinkSmallModel.swift */; };
AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA69AAF52445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift */; };
AA69AAF82445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA69AAF72445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift */; };
AA7F32AB246C0F7900C965BA /* ListLeftVariableRadioButtonAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7F32AA246C0F7900C965BA /* ListLeftVariableRadioButtonAllTextAndLinksModel.swift */; };
AA7F32AD246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7F32AC246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift */; };
AA85236C244435A20059CC1E /* RadioSwatchCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */; };
AA9972502475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA99724F2475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift */; };
AA997252247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */; };
@ -277,11 +281,13 @@
D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */; };
D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; };
D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; };
D23EA7E82473654300D60C34 /* PanelNavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */; };
D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */; };
D23EA7FE247EBBB700D60C34 /* NavigationLabelButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */; };
D23EA800247EBD6C00D60C34 /* LabelBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */; };
D23EA802247EBED400D60C34 /* ImageBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA801247EBED400D60C34 /* ImageBarButtonItem.swift */; };
D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; };
D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */; };
D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */; };
D2509ED62472EE2F001BFB9D /* NavigationImageButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED52472EE2F001BFB9D /* NavigationImageButtonModel.swift */; };
D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260106423D0CEA700764D80 /* StackModel.swift */; };
D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9B245874F8002DE544 /* BGImageMolecule.swift */; };
D253BB9E2458751F002DE544 /* BGImageMoleculeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */; };
@ -328,6 +334,7 @@
D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */; };
D28A839123CD4FD400DFE4FC /* CornerLabelsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A839023CD4FD400DFE4FC /* CornerLabelsModel.swift */; };
D28A839323CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A839223CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift */; };
D28BA730247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28BA72F247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift */; };
D296E14722A5984C0051EBE7 /* MVMCoreUIViewConstrainingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */; };
D29C94D5242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29C94D4242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift */; };
@ -613,6 +620,8 @@
94CA227A24058533002D6750 /* VerizonNHGeDS-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeDS-Bold.otf"; sourceTree = "<group>"; };
94CA227B24058533002D6750 /* VerizonNHGeTX-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeTX-Regular.otf"; sourceTree = "<group>"; };
94F6516C2437954100631BF9 /* Tabs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tabs.swift; sourceTree = "<group>"; };
AA0A257724766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretBodyTextModel.swift; sourceTree = "<group>"; };
AA0A257924766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretBodyText.swift; sourceTree = "<group>"; };
AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2Buttons.swift; sourceTree = "<group>"; };
AA104B1B24474A76004D2810 /* HeadersH2ButtonsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2ButtonsModel.swift; sourceTree = "<group>"; };
AA11A41E23F15D3100D7962F /* ListRightVariablePayments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePayments.swift; sourceTree = "<group>"; };
@ -629,6 +638,8 @@
AA617AB12453012400910B8F /* ListDeviceComplexLinkSmallModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexLinkSmallModel.swift; sourceTree = "<group>"; };
AA69AAF52445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxBodyText.swift; sourceTree = "<group>"; };
AA69AAF72445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxBodyTextModel.swift; sourceTree = "<group>"; };
AA7F32AA246C0F7900C965BA /* ListLeftVariableRadioButtonAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAllTextAndLinksModel.swift; sourceTree = "<group>"; };
AA7F32AC246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAllTextAndLinks.swift; sourceTree = "<group>"; };
AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchCollectionViewCell.swift; sourceTree = "<group>"; };
AA99724F2475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconAllTextLinksModel.swift; sourceTree = "<group>"; };
AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconAllTextLinks.swift; sourceTree = "<group>"; };
@ -707,11 +718,13 @@
D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescription.swift; sourceTree = "<group>"; };
D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = "<group>"; };
D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = "<group>"; };
D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PanelNavigationItemModelProtocol.swift; sourceTree = "<group>"; };
D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItemProtocol.swift; sourceTree = "<group>"; };
D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationLabelButtonModel.swift; sourceTree = "<group>"; };
D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelBarButtonItem.swift; sourceTree = "<group>"; };
D23EA801247EBED400D60C34 /* ImageBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageBarButtonItem.swift; sourceTree = "<group>"; };
D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = "<group>"; };
D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = "<group>"; };
D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationItemButtonModel.swift; sourceTree = "<group>"; };
D2509ED52472EE2F001BFB9D /* NavigationImageButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationImageButtonModel.swift; sourceTree = "<group>"; };
D253BB9B245874F8002DE544 /* BGImageMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMolecule.swift; sourceTree = "<group>"; };
D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMoleculeModel.swift; sourceTree = "<group>"; };
D256E9922412880000360572 /* Header.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Header.swift; sourceTree = "<group>"; };
@ -756,6 +769,7 @@
D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonViewModel.swift; sourceTree = "<group>"; };
D28A839023CD4FD400DFE4FC /* CornerLabelsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CornerLabelsModel.swift; sourceTree = "<group>"; };
D28A839223CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyCaretLinkImageModel.swift; sourceTree = "<group>"; };
D28BA72F247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationButtomModelProtocol.swift; sourceTree = "<group>"; };
D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewConstrainingProtocol.h; sourceTree = "<group>"; };
D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleMolecule.swift; sourceTree = "<group>"; };
D29C94D4242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUICommonViewsUtility+Extension.swift"; sourceTree = "<group>"; };
@ -892,7 +906,6 @@
D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */,
D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */,
D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */,
D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */,
);
path = ModelProtocols;
sourceTree = "<group>";
@ -1310,8 +1323,12 @@
522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */,
8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */,
8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */,
AA0A257724766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift */,
AA0A257924766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift */,
0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */,
0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */,
AA7F32AA246C0F7900C965BA /* ListLeftVariableRadioButtonAllTextAndLinksModel.swift */,
AA7F32AC246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift */,
AA99724F2475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift */,
AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */,
32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */,
@ -1372,10 +1389,22 @@
path = TwoColumn;
sourceTree = "<group>";
};
D23EA7FC247EBB7500D60C34 /* Buttons */ = {
isa = PBXGroup;
children = (
D28BA72F247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift */,
D2509ED52472EE2F001BFB9D /* NavigationImageButtonModel.swift */,
D23EA801247EBED400D60C34 /* ImageBarButtonItem.swift */,
D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */,
D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */,
);
path = Buttons;
sourceTree = "<group>";
};
D2509ED42472EE0B001BFB9D /* NavigationBar */ = {
isa = PBXGroup;
children = (
D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */,
D23EA7FC247EBB7500D60C34 /* Buttons */,
D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */,
);
path = NavigationBar;
@ -1984,6 +2013,7 @@
files = (
AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */,
5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */,
AA0A257824766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift in Sources */,
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */,
943784F5236B77BB006A1E82 /* Wheel.swift in Sources */,
@ -1991,7 +2021,7 @@
8D3BA9BF2433789900D341BA /* ListThreeColumnInternationalDataDivider.swift in Sources */,
94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */,
D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */,
D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */,
D2509ED62472EE2F001BFB9D /* NavigationImageButtonModel.swift in Sources */,
32F8804824765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift in Sources */,
DBC4391822442197001AB423 /* CaretView.swift in Sources */,
C07065C42395677300FBF997 /* Link.swift in Sources */,
@ -2019,6 +2049,7 @@
D21B7F602437C5BC00051ABF /* MoleculeStackView.swift in Sources */,
0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */,
AA2AD116244EE46800BBFFE3 /* ListDeviceComplexLinkMedium.swift in Sources */,
AA7F32AD246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift in Sources */,
D272F5F92473163100BD1A8F /* BarButtonItem.swift in Sources */,
0A9D09202433796500D2E6C0 /* BarsIndicatorView.swift in Sources */,
D2E2A99423D8CCBC000B42E6 /* HeadlineBodyLinkModel.swift in Sources */,
@ -2137,7 +2168,6 @@
01509D952327ED1900EF99AA /* HeadlineBodyLinkToggle.swift in Sources */,
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */,
D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */,
D23EA7E82473654300D60C34 /* PanelNavigationItemModelProtocol.swift in Sources */,
94F6516D2437954100631BF9 /* Tabs.swift in Sources */,
5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */,
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */,
@ -2171,7 +2201,9 @@
BB2FB3C1247EC1EB00DF73CD /* CollectionViewCenterLayout.swift in Sources */,
D2092349244A51D40044AD09 /* RadioSwatchModel.swift in Sources */,
8DD1E370243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift in Sources */,
D23EA802247EBED400D60C34 /* ImageBarButtonItem.swift in Sources */,
D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */,
D23EA800247EBD6C00D60C34 /* LabelBarButtonItem.swift in Sources */,
01EB368F23609801006832FA /* LabelModel.swift in Sources */,
0A6682AC243531C300AD3CA1 /* Padding.swift in Sources */,
AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */,
@ -2234,6 +2266,7 @@
D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */,
AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */,
522679C223FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift in Sources */,
AA7F32AB246C0F7900C965BA /* ListLeftVariableRadioButtonAllTextAndLinksModel.swift in Sources */,
8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */,
D253BB9E2458751F002DE544 /* BGImageMoleculeModel.swift in Sources */,
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */,
@ -2242,6 +2275,7 @@
BBAA4F03243D8E3B005AAD5F /* RadioBoxes.swift in Sources */,
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */,
D28BA730247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift in Sources */,
0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */,
D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */,
AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */,
@ -2311,6 +2345,7 @@
94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */,
D28A838523CCCA8900DFE4FC /* ScrollerModel.swift in Sources */,
D29DF26C21E6AA0B003B2FB9 /* FLAnimatedImage.m in Sources */,
D23EA7FE247EBBB700D60C34 /* NavigationLabelButtonModel.swift in Sources */,
D28A839123CD4FD400DFE4FC /* CornerLabelsModel.swift in Sources */,
012A88F123985E0100FE3DA1 /* Color.swift in Sources */,
D22D8393241C27B100D3DF69 /* TemplateModel.swift in Sources */,
@ -2361,6 +2396,7 @@
8D3BA9BD2433787000D341BA /* ListThreeColumnInternationalDataDividerModel.swift in Sources */,
D29DF2CB21E7BFCC003B2FB9 /* MFSizeThreshold.m in Sources */,
011D959F240453A1000E3791 /* RuleAllValueChangedModel.swift in Sources */,
AA0A257A24766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift in Sources */,
011D95AD2406BB57000E3791 /* FormHolderProtocol.swift in Sources */,
01509D932327ECFB00EF99AA /* ProgressBar.swift in Sources */,
0A6682AA2435125F00AD3CA1 /* Styler.swift in Sources */,

View File

@ -11,7 +11,7 @@ import UIKit
public typealias FacadeElements = (fill: UIColor?, text: UIColor?, border: UIColor?)
public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWatcherFieldProtocol {
public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWatcherFieldProtocol, EnableableModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------

View File

@ -9,14 +9,13 @@
open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol {
//------------------------------------------------------
// MARK: - Constants
//------------------------------------------------------
private let CARET_VIEW_HEIGHT: Float = 10.5
private let CARET_VIEW_WIDTH: Float = 6.5
//------------------------------------------------------
// MARK: - Properties
//------------------------------------------------------
@ -82,7 +81,7 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol {
setTitleColor(enabledColor, for: .normal)
setTitleColor(disabledColor, for: .disabled)
if let rightCaretView = rightView as? CaretView {
rightCaretView.enabledColor = enabledColor
rightCaretView.disabledColor = disabledColor
@ -123,7 +122,7 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol {
bottomAnchor.constraint(greaterThanOrEqualTo: caretView.bottomAnchor).isActive = true
contentHorizontalAlignment = .left
//set correct color after layout
// Set correct color after layout
changeCaretColor()
}
@ -135,6 +134,7 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol {
//------------------------------------------------------
// MARK: - Atomization
//------------------------------------------------------
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let model = model as? CaretLinkModel else { return }
@ -143,10 +143,8 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol {
backgroundColor = color.uiColor
}
enabledColor = model.enabledColor.uiColor
if let color = model.disabledColor {
disabledColor = color.uiColor
}
enabledColor = (model.inverted ? model.enabledColor_inverted : model.enabledColor).uiColor
disabledColor = (model.inverted ? model.disabledColor_inverted : model.disabledColor).uiColor
isEnabled = model.enabled
set(with: model.action, delegateObject: delegateObject, additionalData: additionalData)

View File

@ -9,46 +9,86 @@
import Foundation
import MVMCore
public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol {
public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "caretLink"
public var backgroundColor: Color?
public var title: String
public var action: ActionModelProtocol
public var enabledColor: Color = Color(uiColor: .black)
public var disabledColor: Color? = Color(uiColor: .mvmCoolGray6)
public var enabledColor: Color = Color(uiColor: .mvmBlack)
public var disabledColor: Color = Color(uiColor: .mvmCoolGray6)
public var enabledColor_inverted: Color = Color(uiColor: .mvmWhite)
public var disabledColor_inverted: Color = Color(uiColor: .mvmCoolGray10)
public var enabled = true
public var inverted = false
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(title: String, action: ActionModelProtocol) {
self.title = title
self.action = action
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case backgroundColor
case title
case action
case enabledColor_inverted
case disabledColor_inverted
case enabledColor
case disabledColor
case enabled
case inverted
case moleculeName
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
title = try typeContainer.decode(String.self, forKey: .title)
if let enabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor_inverted) {
self.enabledColor_inverted = enabledColor_inverted
}
if let disabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor_inverted) {
self.disabledColor_inverted = disabledColor_inverted
}
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) {
enabledColor = color
}
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) {
disabledColor = color
}
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
self.enabled = enabled
}
if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.inverted = inverted
}
action = try typeContainer.decodeModel(codingKey: .action)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
@ -58,5 +98,8 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol {
try container.encode(enabled, forKey: .enabledColor)
try container.encodeIfPresent(disabledColor, forKey: .disabledColor)
try container.encode(enabled, forKey: .enabled)
try container.encode(enabledColor_inverted, forKey: .enabledColor_inverted)
try container.encode(disabledColor_inverted, forKey: .disabledColor_inverted)
try container.encode(inverted, forKey: .inverted)
}
}

View File

@ -25,7 +25,7 @@ open class ExternalLink: Link {
guard let model = model as? ExternalLinkModel else { return }
exportImageView?.tintColor = model.enabledColor.uiColor
exportImageView?.tintColor = titleColor(for: model.enabled ? .normal : .disabled)
}
//--------------------------------------------------

View File

@ -8,6 +8,7 @@
import UIKit
open class ExternalLinkModel: LinkModel {
override open class var identifier: String {

View File

@ -37,9 +37,7 @@ import UIKit
}
open override var intrinsicContentSize: CGSize {
guard let size = titleLabel?.intrinsicContentSize else {
return super.intrinsicContentSize
}
guard let size = titleLabel?.intrinsicContentSize else { return super.intrinsicContentSize }
return CGSize(width: size.width, height: size.height + 2)
}
@ -49,17 +47,18 @@ import UIKit
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? LinkModel else { return }
setTitle(model.title, for: .normal)
setTitleColor(model.enabledColor.uiColor, for: .normal)
setTitleColor(model.disabledColor.uiColor, for: .disabled)
setTitleColor((model.inverted ? model.enabledColor_inverted : model.enabledColor).uiColor, for: .normal)
setTitleColor((model.inverted ? model.disabledColor_inverted : model.disabledColor).uiColor, for: .disabled)
isEnabled = model.enabled
set(with: model.action, delegateObject: delegateObject, additionalData: additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 31.0
return 31
}
}
@ -68,12 +67,15 @@ extension Link {
open override func updateView(_ size: CGFloat) {
super.updateView(size)
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
var width = size
if MVMCoreGetterUtility.fequal(a: Float(CGFloat.leastNormalMagnitude), b: Float(size)) {
if MVMCoreGetterUtility.fequal(a: Float.leastNormalMagnitude, b: Float(size)) {
width = MVMCoreUIUtility.getWidth()
}
self.titleLabel?.font = MFStyler.fontB2(forWidth: width)
}
}

View File

@ -8,7 +8,8 @@
import UIKit
open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
@ -22,7 +23,10 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
public var action: ActionModelProtocol
public var enabled = true
public var enabledColor = Color(uiColor: .mvmBlack)
public var enabledColor_inverted = Color(uiColor: .mvmWhite)
public var disabledColor = Color(uiColor: .mvmCoolGray6)
public var disabledColor_inverted = Color(uiColor: .mvmCoolGray10)
public var inverted = false
//--------------------------------------------------
// MARK: - Initializer
@ -44,7 +48,10 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
case action
case enabled
case enabledColor
case enabledColor_inverted
case disabledColor
case disabledColor_inverted
case inverted
}
//--------------------------------------------------
@ -53,6 +60,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
title = try typeContainer.decode(String.self, forKey: .title)
action = try typeContainer.decodeModel(codingKey: .action)
@ -60,12 +68,25 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
self.enabled = enabled
}
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) {
enabledColor = color
if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.inverted = inverted
}
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) {
disabledColor = color
if let enabledColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) {
self.enabledColor = enabledColor
}
if let enabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor_inverted) {
self.enabledColor_inverted = enabledColor_inverted
}
if let disabledColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) {
self.disabledColor = disabledColor
}
if let disabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor_inverted) {
self.disabledColor_inverted = disabledColor_inverted
}
}
@ -75,8 +96,11 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeModel(action, forKey: .action)
try container.encode(inverted, forKey: .inverted)
try container.encode(enabled, forKey: .enabled)
try container.encode(enabledColor, forKey: .enabledColor)
try container.encode(enabledColor_inverted, forKey: .enabledColor_inverted)
try container.encode(disabledColor, forKey: .disabledColor)
try container.encode(disabledColor_inverted, forKey: .disabledColor_inverted)
}
}

View File

@ -97,7 +97,7 @@ import MVMCore
public var disabledCheckColor: UIColor = .mvmCoolGray3
/// Color of the check mark.
public var checkColor: UIColor = .black {
public var checkColor: UIColor = .mvmBlack {
didSet {
setShapeLayerStrokeColor(checkColor)
}
@ -111,7 +111,7 @@ import MVMCore
}
/// border color of the Checkbox
public var borderColor: UIColor = .black {
public var borderColor: UIColor = .mvmBlack {
didSet {
layer.borderColor = borderColor.cgColor
}
@ -126,7 +126,7 @@ import MVMCore
didSet {
if !updateSelectionOnly {
layoutIfNeeded()
(model as? CheckboxModel)?.isChecked = isSelected
(model as? CheckboxModel)?.checked = isSelected
shapeLayer?.removeAllAnimations()
updateCheckboxUI(isSelected: isSelected, isAnimated: isAnimated)
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
@ -375,10 +375,10 @@ import MVMCore
shapeLayer?.removeFromSuperlayer()
shapeLayer = nil
backgroundColor = .clear
borderColor = .black
borderWidth = 1.0
checkColor = .black
checkWidth = 2.0
borderColor = .mvmBlack
borderWidth = 1
checkColor = .mvmBlack
checkWidth = 2
checkAndBypassAnimations(selected: false)
}
@ -393,32 +393,34 @@ import MVMCore
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? CheckboxModel else { return }
self.delegateObject = delegateObject
guard let model = model as? CheckboxModel else { return }
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
if let fieldKey = model.fieldKey {
self.fieldKey = fieldKey
}
borderColor = model.borderColor.uiColor
borderColor = (model.inverted ? model.invertedColor : model.borderColor).uiColor
borderWidth = model.borderWidth
checkColor = model.checkColor.uiColor
unCheckedBackgroundColor = model.unCheckedBackgroundColor.uiColor
checkedBackgroundColor = model.checkedBackgroundColor.uiColor
disabledCheckColor = model.disabledCheckColor.uiColor
disabledBorderColor = model.disabledBorderColor.uiColor
disabledBackgroundColor = model.disabledBackgroundColor.uiColor
checkColor = (model.inverted ? model.invertedColor : model.checkColor).uiColor
unCheckedBackgroundColor = (model.inverted ? model.invertedBackgroundColor : model.unCheckedBackgroundColor).uiColor
checkedBackgroundColor = (model.inverted ? model.invertedBackgroundColor : model.checkedBackgroundColor).uiColor
disabledCheckColor = (model.inverted ? model.invertedColor : model.disabledCheckColor).uiColor
disabledBorderColor = (model.inverted ? model.invertedColor : model.disabledBorderColor).uiColor
disabledBackgroundColor = (model.inverted ? model.invertedColor : model.disabledBackgroundColor).uiColor
isAnimated = model.isAnimated
isRound = model.isRound
isAnimated = model.animated
isRound = model.round
if model.isChecked {
checkAndBypassAnimations(selected: model.isChecked)
if model.checked {
checkAndBypassAnimations(selected: model.checked)
}
isEnabled = model.isEnabled
isEnabled = model.enabled
if let action = model.action {
actionBlock = {

View File

@ -8,6 +8,7 @@
import Foundation
@objcMembers public class CheckboxModel: MoleculeModelProtocol, FormFieldProtocol {
//--------------------------------------------------
// MARK: - Properties
@ -15,20 +16,23 @@ import Foundation
public static var identifier: String = "checkbox"
public var backgroundColor: Color?
public var isChecked: Bool = false
public var isEnabled: Bool = true
public var isAnimated: Bool = true
public var isRound: Bool = false
public var checked: Bool = false
public var enabled: Bool = true
public var animated: Bool = true
public var inverted: Bool = false
public var round: Bool = false
public var borderWidth: CGFloat = 1
public var borderColor: Color = Color(uiColor: .black)
public var checkColor: Color = Color(uiColor: .black)
public var borderColor: Color = Color(uiColor: .mvmBlack)
public var checkColor: Color = Color(uiColor: .mvmBlack)
public var unCheckedBackgroundColor: Color = Color(uiColor: .clear)
public var checkedBackgroundColor: Color = Color(uiColor: .clear)
public var disabledBackgroundColor: Color = Color(uiColor: .clear)
public var disabledBorderColor: Color = Color(uiColor: .mvmCoolGray3)
public var disabledCheckColor: Color = Color(uiColor: .mvmCoolGray3)
public var invertedColor: Color = Color(uiColor: .mvmWhite)
public var invertedBackgroundColor: Color = Color(uiColor: .mvmBlack)
public var action: ActionModelProtocol?
public var fieldKey: String?
public var groupName: String = FormValidator.defaultGroupName
public var baseValue: AnyHashable?
@ -39,13 +43,16 @@ import Foundation
private enum CodingKeys: String, CodingKey {
case moleculeName
case isChecked = "checked"
case isEnabled = "enabled"
case isAnimated = "animated"
case isRound = "round"
case checked
case enabled
case inverted
case animated
case round
case borderWidth
case borderColor
case checkColor
case invertedColor
case invertedBackgroundColor
case unCheckedBackgroundColor
case checkedBackgroundColor
case disabledBackgroundColor
@ -56,12 +63,20 @@ import Foundation
case groupName
}
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
public func formFieldValue() -> AnyHashable? {
return isChecked
return checked
}
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(isChecked: Bool = false) {
self.isChecked = isChecked
self.checked = isChecked
baseValue = isChecked
}
@ -71,22 +86,72 @@ import Foundation
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) ?? 1
borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) ?? Color(uiColor: .black)
checkColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkColor) ?? Color(uiColor: .black)
unCheckedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .unCheckedBackgroundColor) ?? Color(uiColor: .clear)
checkedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkedBackgroundColor) ?? Color(uiColor: .clear)
disabledBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBackgroundColor) ?? Color(uiColor: .clear)
disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor) ?? Color(uiColor: .mvmCoolGray3)
disabledCheckColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledCheckColor) ?? Color(uiColor: .mvmCoolGray3)
isChecked = try typeContainer.decodeIfPresent(Bool.self, forKey: .isChecked) ?? false
isAnimated = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAnimated) ?? true
isRound = try typeContainer.decodeIfPresent(Bool.self, forKey: .isRound) ?? false
isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEnabled) ?? true
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
baseValue = isChecked
if let borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) {
self.borderWidth = borderWidth
}
if let borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) {
self.borderColor = borderColor
}
if let checkColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkColor) {
self.checkColor = checkColor
}
if let unCheckedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .unCheckedBackgroundColor) {
self.unCheckedBackgroundColor = unCheckedBackgroundColor
}
if let checkedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkedBackgroundColor) {
self.checkedBackgroundColor = checkedBackgroundColor
}
if let disabledBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBackgroundColor) {
self.disabledBackgroundColor = disabledBackgroundColor
}
if let disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor) {
self.disabledBorderColor = disabledBorderColor
}
if let disabledCheckColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledCheckColor) {
self.disabledCheckColor = disabledCheckColor
}
if let invertedColor = try typeContainer.decodeIfPresent(Color.self, forKey: .invertedColor) {
self.invertedColor = invertedColor
}
if let invertedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .invertedBackgroundColor) {
self.invertedBackgroundColor = invertedBackgroundColor
}
if let checked = try typeContainer.decodeIfPresent(Bool.self, forKey: .checked) {
self.checked = checked
}
baseValue = checked
if let animated = try typeContainer.decodeIfPresent(Bool.self, forKey: .animated) {
self.animated = animated
}
if let round = try typeContainer.decodeIfPresent(Bool.self, forKey: .round) {
self.round = round
}
if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.inverted = inverted
}
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
self.enabled = enabled
}
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
self.groupName = groupName
}
@ -99,16 +164,19 @@ import Foundation
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(borderColor, forKey: .borderColor)
try container.encode(borderWidth, forKey: .borderWidth)
try container.encode(isChecked, forKey: .isChecked)
try container.encode(checked, forKey: .checked)
try container.encode(inverted, forKey: .inverted)
try container.encodeIfPresent(checkColor, forKey: .checkColor)
try container.encodeIfPresent(invertedColor, forKey: .invertedColor)
try container.encodeIfPresent(invertedBackgroundColor, forKey: .invertedBackgroundColor)
try container.encodeIfPresent(unCheckedBackgroundColor, forKey: .unCheckedBackgroundColor)
try container.encodeIfPresent(checkedBackgroundColor, forKey: .checkedBackgroundColor)
try container.encodeIfPresent(disabledBorderColor, forKey: .disabledBorderColor)
try container.encodeIfPresent(disabledBackgroundColor, forKey: .disabledBackgroundColor)
try container.encodeIfPresent(disabledCheckColor, forKey: .disabledCheckColor)
try container.encodeIfPresent(isAnimated, forKey: .isAnimated)
try container.encodeIfPresent(isRound, forKey: .isRound)
try container.encodeIfPresent(isEnabled, forKey: .isEnabled)
try container.encodeIfPresent(animated, forKey: .animated)
try container.encodeIfPresent(round, forKey: .round)
try container.encodeIfPresent(enabled, forKey: .enabled)
try container.encodeModelIfPresent(action, forKey: .action)
try container.encodeIfPresent(groupName, forKey: .groupName)
}

View File

@ -125,9 +125,9 @@ import UIKit
/// Adjust accessibility label based on state of RadioButton.
func updateAccessibilityLabel() {
if let state = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "radio_selected_state" : "radio_not_selected_state") {
accessibilityLabel = state
if let message = MVMCoreUIUtility.hardcodedString(withKey: "radio_button"),
let selectedState = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "radio_selected_state" : "radio_not_selected_state") {
accessibilityLabel = message + selectedState
}
}

View File

@ -41,8 +41,17 @@ open class Arrow: View {
}
open var color: UIColor {
get { return arrowModel?.color.uiColor ?? .mvmBlack }
set { arrowModel?.color = Color(uiColor: newValue) }
get {
guard let model = arrowModel else { return .mvmBlack }
return model.inverted ? model.color_inverted.uiColor : model.color.uiColor
}
set {
if let model = arrowModel, model.inverted {
model.color_inverted = Color(uiColor: newValue)
} else {
arrowModel?.color = Color(uiColor: newValue)
}
}
}
open var degrees: Float {

View File

@ -22,11 +22,13 @@ open class ArrowModel: MoleculeModelProtocol {
public var backgroundColor: Color?
public var disabledColor: Color = Color(uiColor: .mvmCoolGray3)
public var color: Color = Color(uiColor: .mvmBlack)
public var color_inverted: Color = Color(uiColor: .mvmWhite)
public var degrees: Float = 0
public var lineWidth: CGFloat = 1
public var height: CGFloat = 12
public var width: CGFloat = 12
public var enabled: Bool = true
public var inverted: Bool = false
//--------------------------------------------------
// MARK: - Enum
@ -64,6 +66,7 @@ open class ArrowModel: MoleculeModelProtocol {
case height
case width
case enabled
case inverted
}
//--------------------------------------------------
@ -79,6 +82,10 @@ open class ArrowModel: MoleculeModelProtocol {
self.disabledColor = disabledColor
}
if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.inverted = inverted
}
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) {
self.color = color
}

View File

@ -13,14 +13,13 @@ open class CaretView: View {
//------------------------------------------------------
private var caretPath: UIBezierPath = UIBezierPath()
public var strokeColor: UIColor = .black
public var lineWidth: CGFloat = 1
public var direction: Direction = .right
public var size: CaretSize?
public var enabledColor: UIColor = .black
public var disabledColor: UIColor = .mfSilver()
public var enabledColor: UIColor = .mvmBlack
public var disabledColor: UIColor = .mvmCoolGray3
//------------------------------------------------------
// MARK: - Property Observer
@ -28,7 +27,7 @@ open class CaretView: View {
public var isEnabled: Bool = true {
didSet {
strokeColor = isEnabled ? enabledColor : disabledColor
guard isEnabled != oldValue else { return }
setNeedsDisplay()
}
}
@ -49,7 +48,7 @@ open class CaretView: View {
case horizontal
}
// Dimensions of container; provided by InVision design.
/// Dimensions of container; provided by InVision design.
func dimensions() -> CGSize {
switch self {
@ -92,7 +91,7 @@ open class CaretView: View {
//------------------------------------------------------
@objc override open func setupView() {
super.setupView()
defaultState()
}
@ -141,7 +140,7 @@ open class CaretView: View {
caretPath.addLine(to: CGPoint(x: frame.size.width - inset, y: frame.size.height - inset))
}
strokeColor.setStroke()
enabledColor.setStroke()
caretPath.stroke()
}
@ -151,17 +150,16 @@ open class CaretView: View {
@objc public func setLineColor(_ color: UIColor) {
strokeColor = color
enabledColor = color
setNeedsDisplay()
}
@objc public func defaultState() {
translatesAutoresizingMaskIntoConstraints = false
isOpaque = false
isHidden = false
backgroundColor = .clear
strokeColor = .black
enabledColor = .mvmBlack
}
/// Ensure you have defined a CaretSize with Orientation before calling.
@ -177,8 +175,8 @@ open class CaretView: View {
// MARK: - Atomization
//------------------------------------------------------
// Default values for view.
public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
/// Default values for view.
public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.init(frame: .zero)
defaultState()
set(with: model, delegateObject, additionalData)
@ -186,20 +184,21 @@ open class CaretView: View {
override public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let caretModel = model as? CaretViewModel else {
return
}
strokeColor = caretModel.strokeColor.uiColor
isHidden = caretModel.isHidden ?? false
isOpaque = caretModel.isOpaque ?? false
if let lineWidthValue = caretModel.lineWidth {
lineWidth = lineWidthValue
guard let model = model as? CaretViewModel else { return }
enabledColor = (model.inverted ? model.strokeColor_inverted : model.strokeColor).uiColor
isHidden = model.isHidden
isOpaque = model.isOpaque
if let lineWidthValue = model.lineWidth {
lineWidth = lineWidthValue
}
}
}
extension CaretView: MVMCoreUIViewConstrainingProtocol {
open func needsToBeConstrained() -> Bool {
return true
}

View File

@ -8,32 +8,65 @@
import Foundation
@objcMembers public class CaretViewModel: MoleculeModelProtocol {
@objcMembers public class CaretViewModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "caretView"
public var backgroundColor: Color?
public var strokeColor: Color = Color(uiColor: .black)
public var isHidden: Bool?
public var isOpaque: Bool?
public var strokeColor: Color = Color(uiColor: .mvmBlack)
public var strokeColor_inverted: Color = Color(uiColor: .mvmWhite)
public var isHidden: Bool = false
public var isOpaque: Bool = false
public var inverted: Bool = false
public var lineWidth: CGFloat?
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case backgroundColor
case strokeColor
case strokeColor_inverted
case isHidden
case isOpaque
case lineWidth
case inverted
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
if let strokeColor = try typeContainer.decodeIfPresent(Color.self, forKey: .strokeColor) {
self.strokeColor = strokeColor
}
if let strokeColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .strokeColor_inverted) {
self.strokeColor_inverted = strokeColor_inverted
}
if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.inverted = inverted
}
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden)
isOpaque = try typeContainer.decodeIfPresent(Bool.self, forKey: .isOpaque)
if let isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden) {
self.isHidden = isHidden
}
if let isOpaque = try typeContainer.decodeIfPresent(Bool.self, forKey: .isOpaque) {
self.isOpaque = isOpaque
}
lineWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .lineWidth)
}
@ -41,6 +74,8 @@ import Foundation
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(strokeColor, forKey: .strokeColor)
try container.encode(strokeColor_inverted, forKey: .strokeColor_inverted)
try container.encode(inverted, forKey: .inverted)
try container.encodeIfPresent(isHidden, forKey: .isHidden)
try container.encodeIfPresent(isOpaque, forKey: .isOpaque)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)

View File

@ -68,12 +68,7 @@ open class BarsIndicatorView: CarouselIndicator {
get { return super.indicatorColor }
set (newColor) {
super.indicatorColor = newColor
if isEnabled {
for (i, barTuple) in barReferences.enumerated() {
barTuple.view.backgroundColor = i == currentIndex ? currentIndicatorColor : newColor
}
}
refreshBarColors(with: newColor)
}
}
@ -102,6 +97,15 @@ open class BarsIndicatorView: CarouselIndicator {
// MARK: - Methods
//--------------------------------------------------
private func refreshBarColors(with color: UIColor) {
if isEnabled {
for (i, barTuple) in barReferences.enumerated() {
barTuple.view.backgroundColor = i == currentIndex ? currentIndicatorColor : color
}
}
}
func generateBars() {
var bars = [(View, NSLayoutConstraint)]()
@ -142,7 +146,7 @@ open class BarsIndicatorView: CarouselIndicator {
guard let model = model as? BarsCarouselIndicatorModel else { return }
currentIndicatorColor = model.currentIndicatorColor.uiColor
currentIndicatorColor = model.inverted ? model.indicatorColor_inverted.uiColor : model.currentIndicatorColor.uiColor
}
//--------------------------------------------------

View File

@ -78,8 +78,17 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol {
}
public var indicatorColor: UIColor {
get { return carouselIndicatorModel?.indicatorColor.uiColor ?? .mvmBlack }
set { carouselIndicatorModel?.indicatorColor = Color(uiColor: newValue) }
get {
guard let model = carouselIndicatorModel else { return .mvmBlack }
return model.inverted ? model.indicatorColor_inverted.uiColor : model.indicatorColor.uiColor
}
set {
if let model = carouselIndicatorModel, model.inverted {
model.indicatorColor_inverted = Color(uiColor: newValue)
} else {
carouselIndicatorModel?.indicatorColor = Color(uiColor: newValue)
}
}
}
var accessibilityValueFormat: String? {
@ -191,7 +200,7 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol {
guard let model = model as? CarouselIndicatorModel else { return }
indicatorColor = model.indicatorColor.uiColor
indicatorColor = model.inverted ? model.indicatorColor_inverted.uiColor : model.indicatorColor.uiColor
disabledIndicatorColor = model.disabledIndicatorColor.uiColor
currentIndex = model.currentIndex
isEnabled = model.enabled

View File

@ -26,11 +26,13 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro
public var currentIndex: Int = 0
public var animated: Bool = true
public var hidesForSinglePage: Bool = false
public var inverted: Bool = false
/// Set true to make the accessibility value as "Slide #currentPage of #totalPage", otherwise will be "Page #currentPage of #totalPage", default is false
public var accessibilityHasSlidesInsteadOfPage: Bool = false
public var enabled: Bool = true
public var disabledIndicatorColor: Color = Color(uiColor: .mvmCoolGray3)
public var indicatorColor: Color = Color(uiColor: .mvmBlack)
public var indicatorColor_inverted: Color = Color(uiColor: .mvmWhite)
public var position: Float?
/// Allows sendActions() to trigger even if index is already at min/max index.
@ -53,6 +55,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro
case disabledIndicatorColor
case indicatorColor
case position
case inverted
}
//--------------------------------------------------
@ -72,6 +75,10 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro
self.alwaysSendAction = alwaysSendAction
}
if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.inverted = inverted
}
if let position = try typeContainer.decodeIfPresent(Float.self, forKey: .position) {
self.position = position
}
@ -112,6 +119,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro
try container.encode(hidesForSinglePage, forKey: .hidesForSinglePage)
try container.encode(accessibilityHasSlidesInsteadOfPage, forKey: .accessibilityHasSlidesInsteadOfPage)
try container.encode(enabled, forKey: .enabled)
try container.encode(inverted, forKey: .inverted)
try container.encode(disabledIndicatorColor, forKey: .disabledIndicatorColor)
try container.encode(indicatorColor, forKey: .indicatorColor)
try container.encodeIfPresent(position, forKey: .position)

View File

@ -18,10 +18,10 @@ open class DashLine: View {
var dashModel: DashLineModel? {
get { return model as? DashLineModel }
}
//TODO: Need this for BAU. Can remove once we fix BAU
public var dashColor: UIColor?
@objc private var dashLayer: CAShapeLayer?
//------------------------------------------------------
@ -65,15 +65,15 @@ open class DashLine: View {
path.addLine(to: CGPoint(x: dashLayer.frame.size.width, y: 0))
path.stroke()
dashLayer.strokeStart = 0.0
dashLayer.strokeStart = 0
dashLayer.lineWidth = 1
dashLayer.lineJoin = .miter
dashLayer.lineCap = .round
dashLayer.lineDashPattern = [NSNumber(value: 2), NSNumber(value: 2)]
dashLayer.path = path.cgPath
dashLayer.strokeColor = dashModel?.dashColor.cgColor ?? dashColor?.cgColor
dashLayer.strokeColor = dashColor?.cgColor
dashLayer.fillColor = UIColor.clear.cgColor
dashLayer.backgroundColor = backgroundColor?.cgColor ?? UIColor.white.cgColor
dashLayer.backgroundColor = (dashModel?.inverted ?? false) ? UIColor.mvmBlack.cgColor : backgroundColor?.cgColor ?? UIColor.mvmWhite.cgColor
self.dashLayer = dashLayer
}
@ -81,21 +81,21 @@ open class DashLine: View {
// MARK: - Atomization
//------------------------------------------------------
// Default values for view.
@objc open override func reset() {
backgroundColor = .clear
super.reset()
isHidden = false
}
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let dashLineModel = dashModel else {
return
}
if let isHiddenValue = dashLineModel.isHidden {
isHidden = isHiddenValue
}
if let backgroundColor = dashLineModel.backgroundColor {
guard let model = dashModel else { return }
isHidden = model.isHidden
dashColor = (model.inverted ? model.dashColor_inverted : model.dashColor).uiColor
if let backgroundColor = model.backgroundColor {
dashLayer?.backgroundColor = backgroundColor.uiColor.cgColor
}
}

View File

@ -8,38 +8,66 @@
import Foundation
@objcMembers public class DashLineModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "dashLine"
public var backgroundColor: Color?
public var dashColor: Color = Color(uiColor: .mvmCoolGray3)
public var dashColor_inverted: Color = Color(uiColor: .mvmWhite)
public var isHidden: Bool = false
public var inverted: Bool = false
public var dashColor: Color = Color(uiColor: .mfLighterGray())
public var isHidden: Bool?
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(dashColor: Color) {
self.dashColor = dashColor
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case backgroundColor
case dashColor_inverted
case dashColor
case isHidden
}
//--------------------------------------------------
// MARK: - codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
if let dashColor = try typeContainer.decodeIfPresent(Color.self, forKey: .dashColor) {
self.dashColor = dashColor
}
if let dashColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .dashColor_inverted) {
self.dashColor_inverted = dashColor_inverted
}
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden)
if let isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden) {
self.isHidden = isHidden
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(dashColor, forKey: .dashColor)
try container.encodeIfPresent(isHidden, forKey: .isHidden)
try container.encode(isHidden, forKey: .isHidden)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
}
}

View File

@ -8,14 +8,27 @@
import UIKit
@objcMembers open class Line: View {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
var lineModel: LineModel? {
get { return model as? LineModel }
}
var lineBackgroundColor: Color? {
return (lineModel?.inverted ?? false) ? lineModel?.backgroundColor_inverted : lineModel?.backgroundColor
}
//--------------------------------------------------
// MARK: - Constraints
//--------------------------------------------------
public var heightConstraint: NSLayoutConstraint?
public var widthConstraint: NSLayoutConstraint?
open func updateLineConstraints(constant: CGFloat) {
if let useVerticalLine = lineModel?.useVerticalLine, useVerticalLine {
heightConstraint?.isActive = false
@ -28,7 +41,21 @@ import UIKit
}
}
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public convenience init(pinTo view: UIView, edge: UIRectEdge, useMargin: Bool) {
self.init(frame: .zero)
addLine(to: view, edge: edge, useMargin: useMargin)
}
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
open func setStyle(_ style: LineModel.Style) {
switch style {
case .standard:
updateLineConstraints(constant: 1)
@ -47,25 +74,23 @@ import UIKit
}
}
// MARK: - Helpers
open func shouldBeVisible() -> Bool {
guard let type = lineModel?.type else { return false }
return type != .none
}
public convenience init(pinTo view: UIView, edge: UIRectEdge, useMargin: Bool) {
self.init(frame: .zero)
addLine(to: view, edge: edge, useMargin: useMargin)
}
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
//--------------------------------------------------
open func addLine(to view: UIView, edge: UIRectEdge, useMargin: Bool) {
view.addSubview(self)
NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: self, useMargins: useMargin, pinTop: edge != .bottom, pinBottom: edge != .top, pinLeft: edge != .right, pinRight: edge != .left).values))
}
// MARK: - MVMCoreViewProtocol
open override func setupView() {
super.setupView()
heightConstraint = heightAnchor.constraint(equalToConstant: 1)
heightConstraint?.isActive = true
widthConstraint = widthAnchor.constraint(equalToConstant: 1)
@ -73,9 +98,9 @@ import UIKit
setStyle(.standard)
}
// MARK: - MoleculeViewProtocol
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
if let lineModel = model as? LineModel {
setStyle(lineModel.type)
}
@ -86,7 +111,9 @@ import UIKit
}
public override static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
guard let type = (model as? LineModel)?.type else { return 1 }
switch type {
case .none:
return 0

View File

@ -8,15 +8,19 @@
import UIKit
@objcMembers public class LineModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Enums
//--------------------------------------------------
/*
The frequency of the line in a moleculeList.
all (between all cells, above top, below bottom)
allExceptTop (between all cells, below bottom)
allExceptBottom (between all cells, above top)
between (between all cells)
*/
/**
The frequency of the line in a moleculeList:
- all (between all cells, above top, below bottom)
- allExceptTop (between all cells, below bottom)
- allExceptBottom (between all cells, above top)
- between (between all cells)
*/
public enum Frequency: String, Codable {
case all
case allExceptTop
@ -24,14 +28,14 @@ import UIKit
case between
}
/*
The style of the line.
standard (1 height, silver)
thin (1 height, black)
medium (2 height, black)
heavy (4 height, black)
none (hidden)
*/
/**
The style of the line:
- standard (1 height, silver)
- thin (1 height, black)
- medium (2 height, black)
- heavy (4 height, black)
- none (hidden)
*/
public enum Style: String, Codable {
case standard
case thin
@ -40,50 +44,83 @@ import UIKit
case none
}
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "line"
public var type: Style = .standard
public var frequency: Frequency? = .allExceptTop
//TODO: use color insted of backgroundColor. Needs server changes
// public var color: Color?
// public var color: Color?
public var backgroundColor: Color?
public var backgroundColor_inverted: Color = Color(uiColor: .mvmWhite)
public var inverted: Bool = false
// Use this to show vertical line
// Default is false
public var useVerticalLine: Bool?
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(type: Style) {
self.type = type
self.useVerticalLine = false
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case type
case backgroundColor
case backgroundColor_inverted
case color
case frequency
case inverted
case useVerticalLine
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
if let type = try typeContainer.decodeIfPresent(Style.self, forKey: .type) {
self.type = type
}
if let frequency = try typeContainer.decodeIfPresent(Frequency.self, forKey: .frequency) {
self.frequency = frequency
}
if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.inverted = inverted
}
if let backgroundColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor_inverted) {
self.backgroundColor_inverted = backgroundColor_inverted
}
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
useVerticalLine = try typeContainer.decodeIfPresent(Bool.self, forKey: .useVerticalLine)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(type, forKey: .type)
try container.encode(inverted, forKey: .inverted)
try container.encodeIfPresent(frequency, forKey: .frequency)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(backgroundColor_inverted, forKey: .backgroundColor_inverted)
try container.encodeIfPresent(useVerticalLine, forKey: .useVerticalLine)
}
}

View File

@ -137,6 +137,11 @@ import Foundation
// Other Molecules
MoleculeObjectMapping.shared()?.register(viewClass: DoughnutChartView.self, viewModelClass: DoughnutChartModel.self)
// Navigation Molecules
try? ModelRegistry.register(NavigationItemModel.self)
try? ModelRegistry.register(NavigationImageButtonModel.self)
try? ModelRegistry.register(NavigationLabelButtonModel.self)
// Other Organisms
MoleculeObjectMapping.shared()?.register(viewClass: Carousel.self, viewModelClass: CarouselModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: BarsIndicatorView.self, viewModelClass: BarsCarouselIndicatorModel.self)
@ -144,9 +149,11 @@ import Foundation
// Designed List Items
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaret.self, viewModelClass: ListLeftVariableIconWithRightCaretModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaretBodyText.self, viewModelClass: ListLeftVariableIconWithRightCaretBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxAllTextAndLinks.self, viewModelClass: ListLeftVariableCheckboxAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonAndPaymentMethod.self, viewModelClass: ListLeftVariableRadioButtonAndPaymentMethodModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonBodyText.self, viewModelClass: ListLeftVariableRadioButtonBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonAllTextAndLinks.self, viewModelClass: ListLeftVariableRadioButtonAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxBodyText.self, viewModelClass: ListLeftVariableCheckboxBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconAllTextLinks.self, viewModelClass: ListLeftVariableIconAllTextLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableNumberedListAllTextAndLinks.self, viewModelClass: ListLeftVariableNumberedListAllTextAndLinksModel.self)

View File

@ -0,0 +1,66 @@
//
// ListLeftVariableIconWithRightCaretBodyText.swift
// MVMCoreUI
//
// Created by Lekshmi S on 21/05/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class ListLeftVariableIconWithRightCaretBodyText: TableViewCell {
//-----------------------------------------------------
// MARK: - Outlets
//-------------------------------------------------------
public let leftImage = LoadImageView()
public let headlineBody = HeadlineBody()
public let rightLabel = Label.createLabelRegularBodySmall(true)
public var stack: Stack<StackModel>
//-----------------------------------------------------
// MARK: - Initializers
//-----------------------------------------------------
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
stack = Stack<StackModel>.createStack(with: [(view: leftImage, model: StackItemModel(horizontalAlignment: .fill)),
(view: headlineBody, model: StackItemModel(horizontalAlignment: .leading)),
(view: rightLabel, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .leading))], axis: .horizontal)
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//-----------------------------------------------------
// MARK: - View Lifecycle
//-------------------------------------------------------
override open func setupView() {
super.setupView()
leftImage.addSizeConstraintsForAspectRatio = true
leftImage.contentMode = .scaleAspectFit
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal)
rightLabel.numberOfLines = 1
addMolecule(stack)
stack.restack()
}
//----------------------------------------------------
// MARK: - Molecule
//------------------------------------------------------
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? ListLeftVariableIconWithRightCaretBodyTextModel else { return }
leftImage.set(with: model.image, delegateObject, additionalData)
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 90
}
open override func reset() {
super.reset()
rightLabel.styleRegularBodySmall(true)
}
}

View File

@ -0,0 +1,56 @@
//
// ListLeftVariableIconWithRightCaretBodyTextModel.swift
// MVMCoreUI
//
// Created by Lekshmi S on 21/05/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class ListLeftVariableIconWithRightCaretBodyTextModel: ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "listLVImgBdy"
public var image: ImageViewModel
public var headlineBody: HeadlineBodyModel
public var rightLabel: LabelModel
override public func setDefaults() {
super.setDefaults()
if image.width == nil, image.height == nil {
image.width = 30
image.height = 30
}
headlineBody.style = .item
headlineBody.headline?.hero = 0
}
public init(image: ImageViewModel, headlineBody: HeadlineBodyModel, rightLabel: LabelModel) {
self.image = image
self.headlineBody = headlineBody
self.rightLabel = rightLabel
super.init()
}
private enum CodingKeys: String, CodingKey {
case moleculeName
case image
case headlineBody
case rightLabel
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody)
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
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(image, forKey: .image)
try container.encode(headlineBody, forKey: .headlineBody)
try container.encode(rightLabel, forKey: .rightLabel)
}
}

View File

@ -0,0 +1,108 @@
//
// ListLeftVariableRadioButtonAllTextAndLinks.swift
// MVMCoreUI
//
// Created by Lekshmi S on 13/05/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class ListLeftVariableRadioButtonAllTextAndLinks: TableViewCell {
//-----------------------------------------------------
// MARK: - Outlets
//-----------------------------------------------------
let radioButton = RadioButton()
let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink()
var stack: Stack<StackModel>
private var observation: NSKeyValueObservation? = nil
//-----------------------------------------------------
// MARK: - Initializers
//-----------------------------------------------------
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
stack = Stack<StackModel>.createStack(with: [(view: radioButton, model: StackItemModel(horizontalAlignment: .fill)),
(view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))],
axis: .horizontal)
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//-----------------------------------------------------
// MARK: - View Lifecycle
//-----------------------------------------------------
override open func setupView() {
super.setupView()
addMolecule(stack)
stack.restack()
accessibilityTraits = radioButton.accessibilityTraits
accessibilityHint = radioButton.accessibilityHint
// Update accessibility label on radio button state change.
observation = observe(\.radioButton.isSelected, options: [.new]) { [weak self] _, _ in
self?.updateAccessibilityLabel()
}
}
//----------------------------------------------------
// MARK: - Molecule
//----------------------------------------------------
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? ListLeftVariableRadioButtonAllTextAndLinksModel else { return}
radioButton.set(with: model.radioButton, delegateObject, additionalData)
eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData)
updateAccessibilityLabel()
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 90
}
public override func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
radioButton.tapAction()
}
func updateAccessibilityLabel() {
var message = ""
radioButton.updateAccessibilityLabel()
if let radioButtonLabel = radioButton.accessibilityLabel {
message += radioButtonLabel + ", "
}
if let eyebrowLabel = eyebrowHeadlineBodyLink.eyebrow.text {
message += eyebrowLabel + ", "
}
if let headlineLabel = eyebrowHeadlineBodyLink.headline.text {
message += headlineLabel + ", "
}
if let bodyLabel = eyebrowHeadlineBodyLink.body.text {
message += bodyLabel
}
let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0
isAccessibilityElement = !linkShowing
radioButton.isAccessibilityElement = linkShowing
eyebrowHeadlineBodyLink.link.isAccessibilityElement = linkShowing
if !linkShowing {
// Make whole cell focusable if no link.
accessibilityLabel = message
} else {
// Allow only radio button and link to be focused on.
radioButton.accessibilityLabel = message
var elements: [UIView] = []
if message.count > 0 {
elements.append(radioButton)
}
if eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0 {
elements.append(eyebrowHeadlineBodyLink.link)
}
accessibilityElements = elements
}
}
}

View File

@ -0,0 +1,55 @@
//
// ListLeftVariableRadioButtonAllTextAndLinksModel.swift
// MVMCoreUI
//
// Created by Lekshmi S on 13/05/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
open class ListLeftVariableRadioButtonAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
open class var identifier: String {
return "listLVRBAll"
}
public var radioButton: RadioButtonModel
public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(radioButton: RadioButtonModel, eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel) {
self.radioButton = radioButton
self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink
super.init()
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case eyebrowHeadlineBodyLink
case radioButton
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
radioButton = try typeContainer.decode(RadioButtonModel.self, forKey: .radioButton)
eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink)
try super.init(from: decoder)
}
open 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(eyebrowHeadlineBodyLink, forKey: .eyebrowHeadlineBodyLink)
try container.encode(radioButton, forKey: .radioButton)
}
}

View File

@ -48,13 +48,11 @@ import UIKit
stack.restack()
eyebrowHeadlineBodyLink.body.textColor = .mvmOrangeAA
eyebrowHeadlineBodyLink.headline.styleBoldBodySmall(true)
radioButton.isAccessibilityElement = false
isAccessibilityElement = true
updateAccessibilityLabel()
accessibilityTraits = .button
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "radio_action_hint")
updateAccessibilityLabel()
accessibilityTraits = radioButton.accessibilityTraits
accessibilityHint = radioButton.accessibilityHint
// Update accessibility label on radio button state change.
observation = observe(\.radioButton.isSelected, options: [.new]) { [weak self] _, _ in
self?.updateAccessibilityLabel()
}
@ -88,30 +86,44 @@ import UIKit
}
func updateAccessibilityLabel() {
var message = MVMCoreUIUtility.hardcodedString(withKey: "radio_button") ?? ""
var message = ""
radioButton.updateAccessibilityLabel()
if let radioButtonLabel = radioButton.accessibilityLabel {
message += radioButtonLabel + ", "
}
if let leftImageLabel = leftImage.accessibilityLabel {
message += leftImageLabel + ", "
}
if let eyebrowLabel = eyebrowHeadlineBodyLink.eyebrow.text {
message += eyebrowLabel + ", "
}
if let headlineLabel = eyebrowHeadlineBodyLink.headline.text {
message += headlineLabel + ", "
}
if let bodyLabel = eyebrowHeadlineBodyLink.body.text {
message += bodyLabel
}
accessibilityLabel = message
let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0
isAccessibilityElement = !linkShowing
radioButton.isAccessibilityElement = linkShowing
eyebrowHeadlineBodyLink.link.isAccessibilityElement = linkShowing
if !linkShowing {
// Make whole cell focusable if no link.
accessibilityLabel = message
} else {
// Allow only radio button and link to be focused on.
radioButton.accessibilityLabel = message
var elements: [UIView] = []
if message.count > 0 {
elements.append(radioButton)
}
if eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0 {
elements.append(eyebrowHeadlineBodyLink.link)
}
accessibilityElements = elements
}
}
}

View File

@ -44,12 +44,15 @@ open class ListLeftVariableRadioButtonBodyText: TableViewCell {
addMolecule(stack)
stack.restack()
// Make the whole cell focusable.
isAccessibilityElement = true
radioButton.isAccessibilityElement = false
accessibilityTraits = .button
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "radio_action_hint")
accessibilityTraits = radioButton.accessibilityTraits
accessibilityHint = radioButton.accessibilityHint
updateAccessibilityLabel()
// Update accessibility label on radio button state change.
observation = observe(\.radioButton.isSelected, options: [.new]) { [weak self] _, _ in
self?.updateAccessibilityLabel()
}
@ -79,7 +82,7 @@ open class ListLeftVariableRadioButtonBodyText: TableViewCell {
func updateAccessibilityLabel() {
var message = MVMCoreUIUtility.hardcodedString(withKey: "radio_button") ?? ""
var message = ""
radioButton.updateAccessibilityLabel()
if let radioButtonLabel = radioButton.accessibilityLabel {

View File

@ -8,6 +8,7 @@
import UIKit
@objcMembers public class RadioButtonLabel: View {
public let radioButton = RadioButton()
@ -35,9 +36,6 @@ import UIKit
open override func setupView() {
super.setupView()
guard subviews.count == 0 else {
return
}
addSubview(radioButton)
radioButton.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor, constant: 0).isActive = true
@ -72,5 +70,4 @@ import UIKit
radioButton.set(with: radioButtonLabelModel.radioButton, delegateObject, additionalData)
label.set(with: radioButtonLabelModel.label, delegateObject, additionalData)
}
}

View File

@ -8,7 +8,12 @@
import Foundation
@objcMembers public class RadioButtonLabelModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "radioButtonLabel"
public var backgroundColor: Color?
public var moleculeName: String

View File

@ -0,0 +1,45 @@
//
// ImageBarButtonItem.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 5/27/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class ImageBarButtonItem: BarButtonItem {
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public static func create(with image: UIImage?) -> Self {
let actionObject = ActionDelegate()
let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:)))
button.actionDelegate = actionObject
return button
}
/// Creates the item with the passed in action.
public static func create(with image: UIImage?, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self {
let button = create(with: image)
button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData)
return button
}
/// Creates the item with the passed in action map.
public static func create(with image: UIImage?, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self {
let button = create(with: image)
button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData)
return button
}
/// Creates the item with the passed in action.
public static func create(with image: UIImage?, action: @escaping BarButtonAction) -> Self {
let button = create(with: image)
button.actionDelegate?.buttonAction = action
return button
}
}

View File

@ -0,0 +1,44 @@
//
// LabelBarButtonItem.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 5/27/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class LabelBarButtonItem: BarButtonItem {
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public static func create(with title: String?) -> Self {
let actionObject = ActionDelegate()
let button = self.init(title: title, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:)))
button.actionDelegate = actionObject
return button
}
/// Creates the item with the passed in action.
public static func create(with title: String?, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self {
let button = create(with: title)
button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData)
return button
}
/// Creates the item with the passed in action map.
public static func create(with title: String?, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self {
let button = create(with: title)
button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData)
return button
}
/// Creates the item with the passed in action.
public static func create(with title: String?, action: @escaping BarButtonAction) -> Self {
let button = create(with: title)
button.actionDelegate?.buttonAction = action
return button
}
}

View File

@ -0,0 +1,17 @@
//
// NavigationButtonModelProtocol.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 5/27/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol NavigationButtonModelProtocol: ButtonModelProtocol {
// TODO: add color setting to models and items
//var color: Color? { get set }
/// Returns a bar button item created using data from the model.
func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> UIBarButtonItem
}

View File

@ -7,9 +7,12 @@
import Foundation
public class NavigationItemButtonModel: Codable {
var imageName: String
var action: ActionModelProtocol
public class NavigationImageButtonModel: NavigationButtonModelProtocol, MoleculeModelProtocol {
public var backgroundColor: Color?
public static var identifier: String = "navigationImageButton"
public var imageName: String
public var action: ActionModelProtocol
public init(with imageName: String, action: ActionModelProtocol) {
self.imageName = imageName
@ -34,8 +37,8 @@ public class NavigationItemButtonModel: Codable {
}
/// Convenience function that creates a BarButtonItem for the model.
public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem {
public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> UIBarButtonItem {
let image = UIImage(named: imageName, in: MVMCoreCache.shared()?.bundleToUseForImages(), compatibleWith: nil)
return BarButtonItem.create(with: image, actionModel: action, delegateObject: delegateObject, additionalData: additionalData)
return ImageBarButtonItem.create(with: image, actionModel: action, delegateObject: delegateObject, additionalData: additionalData)
}
}

View File

@ -0,0 +1,44 @@
//
// NavigationLabelButtonModel.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 5/27/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class NavigationLabelButtonModel: NavigationButtonModelProtocol, MoleculeModelProtocol {
public var backgroundColor: Color?
public static var identifier: String = "navigationLabelButton"
public var title: String
public var action: ActionModelProtocol
public init(with title: String, action: ActionModelProtocol) {
self.title = title
self.action = action
}
private enum CodingKeys: String, CodingKey {
case title
case action
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
title = try typeContainer.decode(String.self, forKey: .title)
action = try typeContainer.decodeModel(codingKey: .action)
}
open func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(title, forKey: .title)
try container.encodeModel(action, forKey: .action)
}
/// Convenience function that creates a BarButtonItem for the model.
public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> UIBarButtonItem {
return LabelBarButtonItem.create(with: title, actionModel: action, delegateObject: delegateObject, additionalData: additionalData)
}
}

View File

@ -8,7 +8,7 @@
import Foundation
public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationItemModelProtocol, MoleculeModelProtocol {
public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtocol {
public class var identifier: String {
return "navigationBar"
}
@ -18,22 +18,15 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt
public var backgroundColor: Color?
public var tintColor: Color
public var line: LineModel?
public var backButton: NavigationItemButtonModel?
public var additionalLeftButtons: [NavigationItemButtonModel]?
public var additionalRightButtons: [NavigationItemButtonModel]?
// Legacy, will remove once menu is gone.
public var showLeftPanelButton: Bool
public var showRightPanelButton: Bool
public var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? = NavigationImageButtonModel(with: "back", action: ActionBackModel())
public var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
public var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
public init() {
hidden = false
backgroundColor = Color(uiColor: .white)
tintColor = Color(uiColor: .black)
line = LineModel(type: .standard)
showLeftPanelButton = true
showRightPanelButton = true
backButton = NavigationItemButtonModel(with: "back", action: ActionBackModel())
}
private enum CodingKeys: String, CodingKey {
@ -56,11 +49,11 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) ?? Color(uiColor: .white)
tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .black)
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
backButton = try typeContainer.decodeIfPresent(NavigationItemButtonModel.self, forKey: .backButton) ?? NavigationItemButtonModel(with: "back", action: ActionBackModel())
showLeftPanelButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .showLeftPanelButton) ?? true
showRightPanelButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .showRightPanelButton) ?? true
additionalLeftButtons = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalLeftButtons)
additionalRightButtons = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalRightButtons)
if let backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol) = try typeContainer.decodeModelIfPresent(codingKey: .backButton) {
self.backButton = backButton
}
additionalLeftButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalLeftButtons)
additionalRightButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalRightButtons)
}
open func encode(to encoder: Encoder) throws {
@ -70,10 +63,8 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt
try container.encode(backgroundColor, forKey: .backgroundColor)
try container.encode(tintColor, forKey: .tintColor)
try container.encodeIfPresent(line, forKey: .line)
try container.encodeIfPresent(backButton, forKey: .backButton)
try container.encode(showLeftPanelButton, forKey: .showLeftPanelButton)
try container.encode(showRightPanelButton, forKey: .showRightPanelButton)
try container.encodeIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons)
try container.encodeIfPresent(additionalRightButtons, forKey: .additionalRightButtons)
try container.encodeModelIfPresent(backButton, forKey: .backButton)
try container.encodeModelsIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons)
try container.encodeModelsIfPresent(additionalRightButtons, forKey: .additionalRightButtons)
}
}

View File

@ -8,6 +8,6 @@
import Foundation
public protocol ButtonModelProtocol: EnableableModelProtocol {
public protocol ButtonModelProtocol {
var action: ActionModelProtocol { get set }
}

View File

@ -14,7 +14,7 @@ public protocol NavigationItemModelProtocol {
var backgroundColor: Color? { get set }
var tintColor: Color { get set }
var line: LineModel? { get set }
var backButton: NavigationItemButtonModel? { get set }
var additionalLeftButtons: [NavigationItemButtonModel]? { get set }
var additionalRightButtons: [NavigationItemButtonModel]? { get set }
var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? { get set }
var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set }
var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set }
}

View File

@ -13,5 +13,5 @@ public protocol PageModelProtocol {
/// Temporary: for legacy response
var screenHeading: String? { get set }
var backgroundColor: Color? { get set }
var navigationItem: (NavigationItemModelProtocol & MoleculeModelProtocol)? { get set }
var navigationBar: (NavigationItemModelProtocol & MoleculeModelProtocol)? { get set }
}

View File

@ -1,14 +0,0 @@
//
// PanelNavigationItemModelProtocol.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 5/18/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol PanelNavigationItemModelProtocol {
var showLeftPanelButton: Bool { get set }
var showRightPanelButton: Bool { get set }
}

View File

@ -26,7 +26,7 @@ import Foundation
public var backgroundColor: Color?
public var screenHeading: String?
public var navigationItem: (NavigationItemModelProtocol & MoleculeModelProtocol)?
public var navigationBar: (NavigationItemModelProtocol & MoleculeModelProtocol)?
public var formRules: [FormGroupRule]?
public var behaviors: [PageBehaviorProtocol]?
@ -49,7 +49,7 @@ import Foundation
case backgroundColor
case formRules
case behaviors
case navigationItem
case navigationBar
}
//--------------------------------------------------
@ -63,7 +63,7 @@ import Foundation
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
formRules = try typeContainer.decodeIfPresent([FormGroupRule].self, forKey: .formRules)
behaviors = try typeContainer.decodeModelsIfPresent(codingKey: .behaviors)
navigationItem = try typeContainer.decodeModelIfPresent(codingKey: .navigationItem)
navigationBar = try typeContainer.decodeModelIfPresent(codingKey: .navigationBar)
}
public func encode(to encoder: Encoder) throws {
@ -73,6 +73,6 @@ import Foundation
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(screenHeading, forKey: .screenHeading)
try container.encodeIfPresent(formRules, forKey: .formRules)
try container.encodeModelIfPresent(navigationItem, forKey: .navigationItem)
try container.encodeModelIfPresent(navigationBar, forKey: .navigationBar)
}
}

View File

@ -8,9 +8,9 @@
public typealias BarButtonAction = (BarButtonItem) -> ()
@objc fileprivate class ActionDelegate: NSObject {
fileprivate var buttonAction: BarButtonAction?
@objc fileprivate func callActionBlock(_ sender: BarButtonItem) {
@objc class ActionDelegate: NSObject {
var buttonAction: BarButtonAction?
@objc func callActionBlock(_ sender: BarButtonItem) {
buttonAction?(sender)
}
}
@ -22,39 +22,7 @@ public typealias BarButtonAction = (BarButtonItem) -> ()
//--------------------------------------------------
open weak var buttonDelegate: ButtonDelegateProtocol?
private var actionDelegate: ActionDelegate?
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public static func create(with image: UIImage?) -> Self {
let actionObject = ActionDelegate()
let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:)))
button.actionDelegate = actionObject
return button
}
/// Creates the item with the passed in action.
public static func create(with image: UIImage?, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self {
let button = create(with: image)
button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData)
return button
}
/// Creates the item with the passed in action map.
public static func create(with image: UIImage?, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self {
let button = create(with: image)
button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData)
return button
}
/// Creates the item with the passed in action.
public static func create(with image: UIImage?, action: @escaping BarButtonAction) -> Self {
let button = create(with: image)
button.actionDelegate?.buttonAction = action
return button
}
var actionDelegate: ActionDelegate?
//--------------------------------------------------
// MARK: - Methods

View File

@ -94,9 +94,11 @@ public typealias ButtonAction = (Button) -> ()
self.backgroundColor = backgroundColor.uiColor
}
guard let model = model as? ButtonModelProtocol else { return }
if let model = model as? EnableableModelProtocol {
isEnabled = model.enabled
}
isEnabled = model.enabled
guard let model = model as? ButtonModelProtocol else { return }
set(with: model.action, delegateObject: delegateObject, additionalData: additionalData)
}

View File

@ -163,8 +163,6 @@ import UIKit
open func createDefaultLegacyNavigationModel() -> NavigationItemModel {
let navigationModel = NavigationItemModel()
navigationModel.title = pageModel?.screenHeading
navigationModel.showLeftPanelButton = isMasterInitiallyAccessible()
navigationModel.showRightPanelButton = isSupportInitiallyAccessible()
if /*(self as? MVMCoreUITabBarPageControlViewController) != nil ||*/ manager != nil || loadObject?.requestParameters?.tabWasPressed ?? false == true {
navigationModel.line = LineModel(type: .none)
}
@ -174,9 +172,9 @@ import UIKit
/// Processes any new data. Called after the page is loaded the first time and on response updates for this page,
open func handleNewData() {
// TODO: remove legacy. Temporary, convert legacy to navigation model.
if pageModel?.navigationItem == nil {
if pageModel?.navigationBar == nil {
let navigationItem = createDefaultLegacyNavigationModel()
pageModel?.navigationItem = navigationItem
pageModel?.navigationBar = navigationItem
}
if formValidator == nil {
@ -191,18 +189,28 @@ import UIKit
// MARK: - Navigation Item (Move to model base)
open func setNavigationController() {
guard let navigationItemModel = pageModel?.navigationItem,
let navigationController = manager?.navigationController ?? navigationController else {
let viewController = manager ?? self
guard let navigationItemModel = pageModel?.navigationBar,
let navigationController = viewController.navigationController else {
MVMCoreUISession.sharedGlobal()?.splitViewController?.parent?.setNeedsStatusBarAppearanceUpdate()
return
}
let viewController = manager ?? self
if navigationController == MVMCoreUISplitViewController.main()?.navigationController,
navigationController.topViewController == viewController {
MVMCoreUISession.sharedGlobal()?.splitViewController?.setupPanels()
showBottomProgressBar()
}
// We additionally want our left items
navigationItem.leftItemsSupplementBackButton = true
NavigationController.set(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
// Special logic when using the split view controller. Legacy Update Panels. Change how this is done.
guard navigationController == MVMCoreUISplitViewController.main()?.navigationController,
navigationController.topViewController == viewController else { return }
MVMCoreUISession.sharedGlobal()?.splitViewController?.setupPanels()
showBottomProgressBar()
MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(isMasterInitiallyAccessible(), for: viewController)
MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(isSupportInitiallyAccessible(), for: viewController)
MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(navigationItemModel.tintColor.uiColor)
}
// Eventually will be moved to server

View File

@ -34,6 +34,7 @@ extension UIColor {
"green33": (.mvmGreen33, "#ABE4BF"),
"green66": (.mvmGreen66, "#57C880"),
"greenShade2": (.mvmGreenShade2, "#0F5B25"),
"greenInverted": (.mvmGreenInverted, "#00AC3E"),
"orange": (.mvmOrange, "#ED7000"),
"orange66": (.mvmOrange66, "#F3A157"),
"orange33": (.mvmOrange33, "#F9D0AB"),
@ -45,6 +46,7 @@ extension UIColor {
"blue66": (.mvmBlue66, "#57B1DF"),
"blueShade1": (.mvmBlueShade1, "#136598"),
"blueShade2": (.mvmBlueShade2, "#0B4467"),
"blueInverted": (.mvmBlueInverted, "#0088CE"),
"yellow": (.mvmYellow, "#FFBC3D"),
"coolGray1": (.mvmCoolGray1, "#F6F6F6"),
"coolGray3": (.mvmCoolGray3, "#D8DADA"),
@ -147,6 +149,9 @@ extension UIColor {
/// HEX: #0F5B25
public static let mvmGreenShade2 = UIColor.color8Bits(red: 15, green: 91, blue: 37)
/// HEX: #00AC3E
public static let mvmGreenInverted = UIColor.color8Bits(red: 0, green: 172, blue: 62)
//--------------------------------------------------
// MARK: - Blue
//--------------------------------------------------
@ -166,6 +171,9 @@ extension UIColor {
/// HEX: #0B4467
public static let mvmBlueShade2 = UIColor.color8Bits(red: 11, green: 68, blue: 103)
/// HEX: #0088CE
public static let mvmBlueInverted = UIColor.color8Bits(red: 0, green: 136, blue: 206)
//--------------------------------------------------
// MARK: - Yellow
//--------------------------------------------------

View File

@ -46,23 +46,25 @@ import UIKit
/// Convenience function for setting the navigation buttons.
public static func setNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
var items: [UIBarButtonItem] = []
var leftItems: [UIBarButtonItem] = []
if let backButtonModel = navigationItemModel.backButton,
navigationController.viewControllers.count > 1 {
items.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
}
if let leftItemModels = navigationItemModel.additionalLeftButtons {
for item in leftItemModels {
items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
leftItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
}
viewController.navigationItem.leftBarButtonItems = items
}
viewController.navigationItem.leftBarButtonItems = leftItems.count > 0 ? leftItems : nil
var rightItems: [UIBarButtonItem] = []
if let rightItemModels = navigationItemModel.additionalRightButtons {
for item in rightItemModels {
items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
rightItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
}
viewController.navigationItem.rightBarButtonItems = items
}
viewController.navigationItem.rightBarButtonItems = rightItems.count > 0 ? rightItems : nil
}
/// Convenience function for setting navigation bar with model.
@ -84,22 +86,8 @@ import UIKit
if let navigationController = navigationController as? NavigationController {
navigationController.separatorView?.isHidden = navigationItemModel.line?.type ?? .standard == .none
}
// Let legacy splitview controller handle buttons for now.
guard navigationController == MVMCoreUISplitViewController.main()?.navigationController,
navigationController.topViewController == viewController else {
// Not the main split view controller, add buttons.
setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
return
}
// Update icons if main navigation controller.
MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(tint)
// Update Panels
if let model = navigationItemModel as? PanelNavigationItemModelProtocol {
MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(model.showLeftPanelButton, for: viewController)
MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(model.showRightPanelButton, for: viewController)
}
// Sets up the navigation buttons.
setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
}
}

View File

@ -107,29 +107,12 @@ CGFloat const PanelAnimationDuration = 0.2;
return (width > 2000 ? MFTwoDrawer : (width > 1000 ? MFOneDrawer : MFNoDrawer));
}
- (nullable UIBarButtonItem *)getBackButtonForViewController:(nonnull UIViewController *)viewController {
if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return self.backButton; }
UIViewController <MVMCoreViewControllerProtocol>*controller = (UIViewController <MVMCoreViewControllerProtocol>*)viewController;
NSDictionary *item = [controller.loadObject.pageJSON dictWithChainOfKeysOrIndexes:@[@"navigationItem",@"backButton"]];
if (!item) { return self.backButton; }
DelegateObject *delegate = [controller delegateObject];
return [self createNavigationItemButtonFrom:item delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil];
}
- (nullable NSArray <UIBarButtonItem *>*)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController {
if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return nil; }
UIViewController <MVMCoreViewControllerProtocol>*controller = (UIViewController <MVMCoreViewControllerProtocol>*)viewController;
NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalLeftButtons"]];
DelegateObject *delegate = [controller delegateObject];
return [self createNavigationItemButtonsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil];
return viewController.navigationItem.leftBarButtonItems;
}
- (nullable NSArray <UIBarButtonItem *>*)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController {
if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return nil; }
UIViewController <MVMCoreViewControllerProtocol>*controller = (UIViewController <MVMCoreViewControllerProtocol>*)viewController;
NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalRightButtons"]];
DelegateObject *delegate = [controller delegateObject];
return [self createNavigationItemButtonsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil];
return viewController.navigationItem.rightBarButtonItems;
}
- (CGFloat)leftPanelExtendedWidth {
@ -251,22 +234,13 @@ CGFloat const PanelAnimationDuration = 0.2;
- (void)setLeftNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended {
NSMutableArray *leftBarButtonItems = [NSMutableArray array];
if ([viewController.navigationController.viewControllers count] > 1) {
UIBarButtonItem *button = [self getBackButtonForViewController:viewController];
if (button) {
viewController.navigationItem.hidesBackButton = YES;
[leftBarButtonItems addObject:button];
} else {
viewController.navigationItem.hidesBackButton = NO;
}
}
if ((accessible && !extended) && self.leftPanelButton) {
[leftBarButtonItems addObject:self.leftPanelButton];
}
NSArray *extraButtons = [self additionalLeftButtonsForViewController:viewController];
if (extraButtons) {
[leftBarButtonItems addObjectsFromArray:extraButtons];
}
if ((accessible && !extended) && self.leftPanelButton) {
[leftBarButtonItems addObject:self.leftPanelButton];
}
[viewController.navigationItem setLeftBarButtonItems:(leftBarButtonItems.count > 0 ? leftBarButtonItems : nil) animated:!DisableAnimations];
}
@ -625,24 +599,6 @@ CGFloat const PanelAnimationDuration = 0.2;
#pragma mark - Other Panel Functions
/// Convenience function, creates a BarButtonItem from button json
- (nonnull UIBarButtonItem *)createNavigationItemButtonFrom:(nonnull NSDictionary *)JSON delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject {
UIImage *image = [UIImage imageNamed:[JSON string:@"imageName"] inBundle:[[MVMCoreCache sharedCache] bundleToUseForImages] compatibleWithTraitCollection:nil];
BarButtonItem *item = [BarButtonItem createWith:image actionMap:[JSON dict:@"action"] delegateObject:delegateObject additionalData:nil];
return item;
}
/// Convenience function, creates a list of BarButtonItems list of json
- (nullable NSArray <UIBarButtonItem *>*)createNavigationItemButtonsFrom:(nullable NSArray <NSDictionary *>*)JSONlist delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject {
if (JSONlist.count == 0) { return nil; }
NSMutableArray *items = [NSMutableArray arrayWithCapacity:JSONlist.count];
for (NSDictionary *itemData in JSONlist) {
UIBarButtonItem *item = [self createNavigationItemButtonFrom:itemData delegateObject:delegateObject];
[items addObject:item];
}
return items;
}
- (void)forceHideBothDrawers {
[self hideBothDrawersShouldForceHide:YES];
}