Merge branch 'develop' into feature/collor_assets

This commit is contained in:
Kevin G Christiano 2020-07-06 12:08:27 -04:00
commit 9ab02bdc4b
90 changed files with 1624 additions and 508 deletions

View File

@ -117,6 +117,8 @@
27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */; };
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; };
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; };
324FB6AA249366F3002552C7 /* ListLeftVariableNumberedListBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 324FB6A9249366F3002552C7 /* ListLeftVariableNumberedListBodyTextModel.swift */; };
324FB6AC24936717002552C7 /* ListLeftVariableNumberedListBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 324FB6AB24936717002552C7 /* ListLeftVariableNumberedListBodyText.swift */; };
32F8804624765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */; };
32F8804824765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32F8804724765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift */; };
522679C123FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */; };
@ -188,6 +190,10 @@
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 */; };
AA104AC724472DB0004D2810 /* HeadersH1Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104AC624472DB0004D2810 /* HeadersH1Button.swift */; };
AA104AC924472DC7004D2810 /* HeadersH1ButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104AC824472DC7004D2810 /* HeadersH1ButtonModel.swift */; };
AA104ADA244734DB004D2810 /* HeadersH1LandingPageHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104AD9244734DB004D2810 /* HeadersH1LandingPageHeader.swift */; };
AA104ADC244734EA004D2810 /* HeadersH1LandingPageHeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104ADB244734EA004D2810 /* HeadersH1LandingPageHeaderModel.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 */; };
@ -202,8 +208,12 @@
AA56A211243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA56A210243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift */; };
AA617AB02453010A00910B8F /* ListDeviceComplexLinkSmall.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA617AAF2453010A00910B8F /* ListDeviceComplexLinkSmall.swift */; };
AA617AB22453012400910B8F /* ListDeviceComplexLinkSmallModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA617AB12453012400910B8F /* ListDeviceComplexLinkSmallModel.swift */; };
AA633B3124989EC000731E80 /* HeadersH2PricingTwoRowsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA633B3024989EC000731E80 /* HeadersH2PricingTwoRowsModel.swift */; };
AA633B3324989ED500731E80 /* HeadersH2PricingTwoRows.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA633B3224989ED500731E80 /* HeadersH2PricingTwoRows.swift */; };
AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA69AAF52445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift */; };
AA69AAF82445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA69AAF72445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift */; };
AA71AD3E24A32FCE00ACA76F /* HeadersH2LinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA71AD3D24A32FCE00ACA76F /* HeadersH2LinkModel.swift */; };
AA71AD4024A32FE700ACA76F /* HeadersH2Link.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA71AD3F24A32FE700ACA76F /* HeadersH2Link.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 */; };
@ -283,6 +293,8 @@
D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */; };
D22D8393241C27B100D3DF69 /* TemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8392241C27B100D3DF69 /* TemplateModel.swift */; };
D22D8395241FB41200D3DF69 /* UIStackView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */; };
D2351C7A24A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */; };
D2351C7C24A4D4C3007DF0BC /* ListRightVariableToggleAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2351C7B24A4D4C3007DF0BC /* ListRightVariableToggleAllTextAndLinks.swift */; };
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 */; };
@ -322,6 +334,7 @@
D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */; };
D27CD4102339057800C1DC07 /* EyebrowHeadlineBodyLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27CD40F2339057800C1DC07 /* EyebrowHeadlineBodyLink.swift */; };
D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */; };
D2874024249BA6F300BE950A /* MVMCoreUISplitViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2874023249BA6F300BE950A /* MVMCoreUISplitViewController+Extension.swift */; };
D28764AA2458980300CB882D /* ThreeLayerFillMiddleTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28764A92458980300CB882D /* ThreeLayerFillMiddleTemplate.swift */; };
D28764AC245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28764AB245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift */; };
D28764F9245A327200CB882D /* TwoLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28764F8245A327200CB882D /* TwoLinkView.swift */; };
@ -563,6 +576,8 @@
27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBrightnessModifierBehavior.swift; sourceTree = "<group>"; };
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = "<group>"; };
31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = "<group>"; };
324FB6A9249366F3002552C7 /* ListLeftVariableNumberedListBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableNumberedListBodyTextModel.swift; sourceTree = "<group>"; };
324FB6AB24936717002552C7 /* ListLeftVariableNumberedListBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableNumberedListBodyText.swift; sourceTree = "<group>"; };
32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableNumberedListAllTextAndLinksModel.swift; sourceTree = "<group>"; };
32F8804724765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableNumberedListAllTextAndLinks.swift; sourceTree = "<group>"; };
522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxAllTextAndLinks.swift; sourceTree = "<group>"; };
@ -634,6 +649,10 @@
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>"; };
AA104AC624472DB0004D2810 /* HeadersH1Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH1Button.swift; sourceTree = "<group>"; };
AA104AC824472DC7004D2810 /* HeadersH1ButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH1ButtonModel.swift; sourceTree = "<group>"; };
AA104AD9244734DB004D2810 /* HeadersH1LandingPageHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH1LandingPageHeader.swift; sourceTree = "<group>"; };
AA104ADB244734EA004D2810 /* HeadersH1LandingPageHeaderModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH1LandingPageHeaderModel.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>"; };
@ -648,8 +667,12 @@
AA56A210243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnSubsectionDivider.swift; sourceTree = "<group>"; };
AA617AAF2453010A00910B8F /* ListDeviceComplexLinkSmall.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexLinkSmall.swift; sourceTree = "<group>"; };
AA617AB12453012400910B8F /* ListDeviceComplexLinkSmallModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexLinkSmallModel.swift; sourceTree = "<group>"; };
AA633B3024989EC000731E80 /* HeadersH2PricingTwoRowsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2PricingTwoRowsModel.swift; sourceTree = "<group>"; };
AA633B3224989ED500731E80 /* HeadersH2PricingTwoRows.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2PricingTwoRows.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>"; };
AA71AD3D24A32FCE00ACA76F /* HeadersH2LinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2LinkModel.swift; sourceTree = "<group>"; };
AA71AD3F24A32FE700ACA76F /* HeadersH2Link.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2Link.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>"; };
@ -729,6 +752,8 @@
D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccordionMoleculeTableViewCell.swift; sourceTree = "<group>"; };
D22D8392241C27B100D3DF69 /* TemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateModel.swift; sourceTree = "<group>"; };
D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+Extension.swift"; sourceTree = "<group>"; };
D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableToggleAllTextAndLinksModel.swift; sourceTree = "<group>"; };
D2351C7B24A4D4C3007DF0BC /* ListRightVariableToggleAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableToggleAllTextAndLinks.swift; sourceTree = "<group>"; };
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>"; };
@ -767,6 +792,7 @@
D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsTableViewCell.swift; sourceTree = "<group>"; };
D27CD40F2339057800C1DC07 /* EyebrowHeadlineBodyLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EyebrowHeadlineBodyLink.swift; sourceTree = "<group>"; };
D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFTransparentGIFView.swift; sourceTree = "<group>"; };
D2874023249BA6F300BE950A /* MVMCoreUISplitViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUISplitViewController+Extension.swift"; sourceTree = "<group>"; };
D28764A92458980300CB882D /* ThreeLayerFillMiddleTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerFillMiddleTemplate.swift; sourceTree = "<group>"; };
D28764AB245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerFillMiddleTemplateModel.swift; sourceTree = "<group>"; };
D28764F8245A327200CB882D /* TwoLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoLinkView.swift; sourceTree = "<group>"; };
@ -1034,12 +1060,8 @@
5206F150241144A900658DC5 /* Headers */ = {
isa = PBXGroup;
children = (
AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */,
AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */,
AA26850D244840C300CE34CC /* HeadersH2TinyButtonModel.swift */,
AA26850B244840AE00CE34CC /* HeadersH2TinyButton.swift */,
AA104B1B24474A76004D2810 /* HeadersH2ButtonsModel.swift */,
AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */,
D287955224A2504C0056BF75 /* H1 */,
D287955324A250550056BF75 /* H2 */,
);
path = Headers;
sourceTree = "<group>";
@ -1140,6 +1162,8 @@
8D8067D22444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift */,
C7F8012223E846C300396FBD /* ListRVWheelModel.swift */,
C7F8012023E8303200396FBD /* ListRVWheel.swift */,
D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */,
D2351C7B24A4D4C3007DF0BC /* ListRightVariableToggleAllTextAndLinks.swift */,
);
path = RightVariable;
sourceTree = "<group>";
@ -1356,6 +1380,8 @@
AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */,
32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */,
32F8804724765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift */,
324FB6A9249366F3002552C7 /* ListLeftVariableNumberedListBodyTextModel.swift */,
324FB6AB24936717002552C7 /* ListLeftVariableNumberedListBodyText.swift */,
);
path = LeftVariable;
sourceTree = "<group>";
@ -1483,6 +1509,34 @@
path = Selectors;
sourceTree = "<group>";
};
D287955224A2504C0056BF75 /* H1 */ = {
isa = PBXGroup;
children = (
AA104AC824472DC7004D2810 /* HeadersH1ButtonModel.swift */,
AA104AC624472DB0004D2810 /* HeadersH1Button.swift */,
AA104ADB244734EA004D2810 /* HeadersH1LandingPageHeaderModel.swift */,
AA104AD9244734DB004D2810 /* HeadersH1LandingPageHeader.swift */,
);
path = H1;
sourceTree = "<group>";
};
D287955324A250550056BF75 /* H2 */ = {
isa = PBXGroup;
children = (
AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */,
AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */,
AA26850D244840C300CE34CC /* HeadersH2TinyButtonModel.swift */,
AA26850B244840AE00CE34CC /* HeadersH2TinyButton.swift */,
AA104B1B24474A76004D2810 /* HeadersH2ButtonsModel.swift */,
AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */,
AA633B3024989EC000731E80 /* HeadersH2PricingTwoRowsModel.swift */,
AA633B3224989ED500731E80 /* HeadersH2PricingTwoRows.swift */,
AA71AD3D24A32FCE00ACA76F /* HeadersH2LinkModel.swift */,
AA71AD3F24A32FE700ACA76F /* HeadersH2Link.swift */,
);
path = H2;
sourceTree = "<group>";
};
D29DF0C221E404D4003B2FB9 = {
isa = PBXGroup;
children = (
@ -1809,6 +1863,7 @@
D29DF15321E69760003B2FB9 /* MVMCoreUIPanelButtonProtocol.h */,
D29DF11A21E684A9003B2FB9 /* MVMCoreUISplitViewController.h */,
D29DF11B21E684A9003B2FB9 /* MVMCoreUISplitViewController.m */,
D2874023249BA6F300BE950A /* MVMCoreUISplitViewController+Extension.swift */,
);
path = SplitViewController;
sourceTree = "<group>";
@ -2057,6 +2112,7 @@
files = (
0A775F2624893916009EFB58 /* ThreeHeadlineBodyLink.swift in Sources */,
AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */,
324FB6AA249366F3002552C7 /* ListLeftVariableNumberedListBodyTextModel.swift in Sources */,
5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */,
AA0A257824766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift in Sources */,
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
@ -2103,6 +2159,7 @@
01004F3022721C3800991ECC /* RadioButton.swift in Sources */,
D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */,
D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */,
AA71AD4024A32FE700ACA76F /* HeadersH2Link.swift in Sources */,
D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */,
D2B18B7F2360913400A9AEDC /* Control.swift in Sources */,
D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */,
@ -2214,6 +2271,7 @@
D2A92886241ACD99004E01C6 /* ProgrammaticTableViewController.swift in Sources */,
BBAA4F05243D8E3B005AAD5F /* RadioBoxesModel.swift in Sources */,
01509D952327ED1900EF99AA /* HeadlineBodyLinkToggle.swift in Sources */,
AA104ADA244734DB004D2810 /* HeadersH1LandingPageHeader.swift in Sources */,
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */,
D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */,
94F6516D2437954100631BF9 /* Tabs.swift in Sources */,
@ -2221,6 +2279,7 @@
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */,
D264FA8E243BCD9A00D98315 /* CollectionTemplate.swift in Sources */,
0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */,
AA633B3124989EC000731E80 /* HeadersH2PricingTwoRowsModel.swift in Sources */,
8DEFA95C243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift in Sources */,
D2092357244FA1EF0044AD09 /* ThreeLayerModelBase.swift in Sources */,
0A1B4A96233BB18F005B3FB4 /* CheckboxLabel.swift in Sources */,
@ -2258,6 +2317,7 @@
942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */,
8D8067D32444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift in Sources */,
8D4687E4242E2DF300802879 /* ListFourColumnDataUsageListItem.swift in Sources */,
D2874024249BA6F300BE950A /* MVMCoreUISplitViewController+Extension.swift in Sources */,
01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */,
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */,
011B58F023A2AA980085F53C /* ListItemModelProtocol.swift in Sources */,
@ -2267,6 +2327,7 @@
BB55B51D244482C1002001AD /* ListRightVariablePriceChangeBodyText.swift in Sources */,
017BEB382360C6AC0024EF95 /* RadioButtonLabel.swift in Sources */,
D28A837923C7D5BC00DFE4FC /* PageModelProtocol.swift in Sources */,
D2351C7C24A4D4C3007DF0BC /* ListRightVariableToggleAllTextAndLinks.swift in Sources */,
017BEB7B236763000024EF95 /* LineModel.swift in Sources */,
D256E9932412880000360572 /* Header.swift in Sources */,
94C2D9A523872C350006CF46 /* LabelAttributeFontModel.swift in Sources */,
@ -2313,14 +2374,17 @@
BB6C6AC0242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift in Sources */,
8DEFA95E243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift in Sources */,
D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */,
324FB6AC24936717002552C7 /* ListLeftVariableNumberedListBodyText.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 */,
AA104AC924472DC7004D2810 /* HeadersH1ButtonModel.swift in Sources */,
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */,
8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */,
BB2FB3BD247E7EF200DF73CD /* Tags.swift in Sources */,
AA104ADC244734EA004D2810 /* HeadersH1LandingPageHeaderModel.swift in Sources */,
BBAA4F03243D8E3B005AAD5F /* RadioBoxes.swift in Sources */,
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */,
@ -2352,6 +2416,7 @@
8D070BB2241B56AD0099AC56 /* ListRightVariableTotalData.swift in Sources */,
D264FAA5243F66A500D98315 /* CollectionTemplateItemProtocol.swift in Sources */,
D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */,
AA71AD3E24A32FCE00ACA76F /* HeadersH2LinkModel.swift in Sources */,
8DD1E36E243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift in Sources */,
D243859923A16B1800332775 /* Container.swift in Sources */,
D2C521A923EDE79E00CA2634 /* ViewController.swift in Sources */,
@ -2361,6 +2426,7 @@
AA26850E244840C300CE34CC /* HeadersH2TinyButtonModel.swift in Sources */,
D260105F23D0BFFC00764D80 /* StackItem.swift in Sources */,
9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */,
D2351C7A24A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift in Sources */,
01EB369323609801006832FA /* HeaderModel.swift in Sources */,
8DE5BECF2456F7B100772E76 /* ListTwoColumnDropdownSelectors.swift in Sources */,
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */,
@ -2386,6 +2452,7 @@
BB54C5202434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift in Sources */,
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */,
013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */,
AA104AC724472DB0004D2810 /* HeadersH1Button.swift in Sources */,
525239C22407BD1000454969 /* ListTwoColumnPriceDetails.swift in Sources */,
AA997252247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift in Sources */,
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */,
@ -2437,6 +2504,7 @@
0A25209824645B76000FA9F6 /* TextViewEntryFieldModel.swift in Sources */,
525019DD2406430800EED91C /* ListProgressBarDataModel.swift in Sources */,
C6FA7D5223C77A4A00A3614A /* UnOrderedList.swift in Sources */,
AA633B3324989ED500731E80 /* HeadersH2PricingTwoRows.swift in Sources */,
01509D8F2327EC6F00EF99AA /* MoleculeTableViewCell.swift in Sources */,
0A6682A22434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift in Sources */,
EA5124FD243601600051A3A4 /* BGImageHeadlineBodyButton.swift in Sources */,

View File

@ -157,9 +157,9 @@ import MVMCore
override public init(frame: CGRect) {
super.init(frame: frame)
accessibilityTraits = .button
isAccessibilityElement = true
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "checkbox_action_hint")
accessibilityTraits = .button
updateAccessibilityLabel()
}

View File

@ -147,8 +147,8 @@ import UIKit
addTarget(self, action: #selector(tapAction), for: .touchUpInside)
isAccessibilityElement = true
accessibilityTraits = .button
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "radio_action_hint")
accessibilityTraits = .button
updateAccessibilityLabel()
}

View File

@ -115,12 +115,12 @@ open class BarsIndicatorView: CarouselIndicator {
for i in 0..<numberOfPages {
let bar = View()
bar.accessibilityTraits = .button
bar.isAccessibilityElement = true
if let accessibleValueFormat = accessibilityValueFormat, let accessibleIndex = ordinalFormatter.string(from: NSNumber(value: i + 1)) {
bar.accessibilityLabel = String(format: accessibleValueFormat, accessibleIndex, numberOfPages)
}
bar.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccTabHint")
bar.accessibilityTraits = .button
bar.widthAnchor.constraint(equalToConstant: BarsIndicatorView.indicatorBarWidth).isActive = true
bar.backgroundColor = isEnabled ? (i == currentIndex ? currentIndicatorColor : indicatorColor) : disabledIndicatorColor
let barHeight = i == currentIndex ? BarsIndicatorView.indicatorBarHeight.selected : BarsIndicatorView.indicatorBarHeight.unselected

View File

@ -63,7 +63,7 @@ import UIKit
addSubview(stack)
NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
stack.backgroundColor = backgroundColor
stack.contentView.backgroundColor = .mvmWhite
stack.contentView.backgroundColor = .clear
stack.model = StackModel(molecules: [], axis: .horizontal, spacing: 2)
stack.stackModel?.horizontalAlignment = .leading
@ -111,7 +111,6 @@ import UIKit
roundedCorners = multiProgressModel.roundedCorners ?? false
thicknessConstraint?.constant = multiProgressModel.thickness ?? defaultHeight
stack.model?.backgroundColor = model.backgroundColor
set(with: multiProgressModel.progressList, delegateObject, additionalData)
}

View File

@ -44,8 +44,8 @@ public typealias ActionBlockConfirmation = () -> (Bool)
}()
// Sizes are from InVision design specs.
static let containerSize = CGSize(width: 46, height: 24)
static let knobSize = CGSize(width: 22, height: 22)
static let containerSize = CGSize(width: 51, height: 31)
static let knobSize = CGSize(width: 28, height: 28)
private var knobView: View = {
let view = View()
@ -62,8 +62,8 @@ public typealias ActionBlockConfirmation = () -> (Bool)
didSet {
isUserInteractionEnabled = isEnabled
changeStateNoAnimation(isEnabled ? isOn : false)
backgroundColor = isEnabled ? (isOn ? containerTintColor.on : containerTintColor.off) : disabledTintColor.container
knobView.backgroundColor = isEnabled ? (isOn ? knobTintColor.on : knobTintColor.off) : disabledTintColor.knob
setToggleAppearanceFromState()
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: isEnabled ? "AccToggleHint" : "AccDisabled")
}
}
@ -96,8 +96,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
}, completion: nil)
} else {
backgroundColor = isOn ? containerTintColor.on : containerTintColor.off
knobView.backgroundColor = isOn ? knobTintColor.on : knobTintColor.off
setToggleAppearanceFromState()
self.constrainKnob()
}
@ -143,14 +142,14 @@ public typealias ActionBlockConfirmation = () -> (Bool)
private func constrainKnobOn() {
knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 1)
knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 2)
knobLeadingConstraint = knobView.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor)
}
private func constrainKnobOff() {
knobTrailingConstraint = trailingAnchor.constraint(greaterThanOrEqualTo: knobView.trailingAnchor)
knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1)
knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 2)
}
//--------------------------------------------------
@ -159,7 +158,6 @@ public typealias ActionBlockConfirmation = () -> (Bool)
public override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
public convenience override init() {
@ -215,17 +213,17 @@ public typealias ActionBlockConfirmation = () -> (Bool)
super.setupView()
isAccessibilityElement = true
accessibilityTraits = .button
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccToggleHint")
accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel")
accessibilityTraits = .button
heightConstraint = heightAnchor.constraint(equalToConstant: Self.containerSize.height)
heightConstraint?.isActive = true
widthConstraint = widthAnchor.constraint(equalToConstant: Self.containerSize.width)
widthConstraint?.isActive = true
layer.cornerRadius = Self.containerSize.height / 2.0
layer.cornerRadius = Self.getContainerHeight() / 2.0
backgroundColor = containerTintColor.off
addSubview(knobView)
@ -305,6 +303,16 @@ public typealias ActionBlockConfirmation = () -> (Bool)
isAnimated = isAnimatedState
}
override open func accessibilityActivate() -> Bool {
// Hold state in case User wanted isAnimated to remain off.
guard isUserInteractionEnabled else { return false }
let isAnimatedState = isAnimated
isAnimated = false
sendActions(for: .touchUpInside)
isAnimated = isAnimatedState
return true
}
//--------------------------------------------------
// MARK: - UIResponder
//--------------------------------------------------
@ -342,6 +350,12 @@ public typealias ActionBlockConfirmation = () -> (Bool)
// MARK: - Animations
//--------------------------------------------------
public func setToggleAppearanceFromState() {
backgroundColor = isEnabled ? isOn ? containerTintColor.on : containerTintColor.off : disabledTintColor.container
knobView.backgroundColor = isEnabled ? isOn ? knobTintColor.on : knobTintColor.off : disabledTintColor.knob
}
public func knobReformAnimation() {
if isAnimated {

View File

@ -32,7 +32,7 @@ import Foundation
url = try typeContainer.decodeIfPresent(URL.self, forKey: .url)
htmlString = try typeContainer.decodeIfPresent(String.self, forKey: .htmlString)
if url == nil, htmlString == nil {
throw ModelRegistry.Error.decoderErrorModelNotMapped
throw ModelRegistry.Error.decoderErrorModelNotMapped()
}
height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height)
borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor)

View File

@ -38,7 +38,7 @@ import Foundation
public func getMoleculeModelForJSON(_ json: [String: Any]) throws -> MoleculeModelProtocol? {
guard let moleculeName = json.optionalStringForKey(KeyMoleculeName),
let type = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self) else {
throw ModelRegistry.Error.decoderErrorModelNotMapped
throw ModelRegistry.Error.decoderErrorModelNotMapped()
}
guard let model = try type.decode(jsonDict: json) as? MoleculeModelProtocol else {
throw ModelRegistry.Error.decoderError
@ -172,6 +172,7 @@ import Foundation
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)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableNumberedListBodyText.self, viewModelClass: ListLeftVariableNumberedListBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTotalData.self, viewModelClass: ListRightVariableTotalDataModel.self)
@ -179,6 +180,7 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableButtonAllTextAndLinks.self, viewModelClass: ListRightVariableButtonAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeBodyText.self, viewModelClass: ListRightVariablePriceChangeBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeAllTextAndLinks.self, viewModelClass: ListRightVariablePriceChangeAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableToggleAllTextAndLinks.self, viewModelClass: ListRightVariableToggleAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextAllTextAndLinks.self, viewModelClass: ListOneColumnFullWidthTextAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextBodyText.self, viewModelClass: ListOneColumnFullWidthTextBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnCompareChanges.self, viewModelClass: ListTwoColumnCompareChangesModel.self)
@ -203,9 +205,13 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnDataUsageDivider.self, viewModelClass: ListThreeColumnDataUsageDividerModel.self)
// Designed Headers
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH1Button.self, viewModelClass: HeadersH1ButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH1LandingPageHeader.self, viewModelClass: HeadersH1LandingPageHeaderModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2NoButtonsBodyText.self, viewModelClass: HeadersH2NoButtonsBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2TinyButton.self, viewModelClass: HeadersH2TinyButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2Buttons.self, viewModelClass: HeadersH2ButtonsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2PricingTwoRows.self, viewModelClass: HeadersH2PricingTwoRowsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2Link.self, viewModelClass: HeadersH2LinkModel.self)
// Device Items
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonMedium.self, viewModelClass: ListDeviceComplexButtonMediumModel.self)

View File

@ -0,0 +1,59 @@
//
// HeadersH1Button.swift
// MVMCoreUI
//
// Created by Lekshmi S on 04/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class HeadersH1Button: HeaderView {
//--------------------------------------------------
// MARK: - Outlets
//--------------------------------------------------
public let headlineBody = HeadlineBody(frame: .zero)
public let buttons = TwoButtonView(frame: .zero)
public let stack: Stack<StackModel>
//-------------------------------------------------------
// MARK: - Initializers
//-------------------------------------------------------
public override init(frame: CGRect) {
stack = Stack<StackModel>.createStack(with: [headlineBody, buttons], spacing: Padding.Eighteen)
super.init(frame: frame)
}
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//-------------------------------------------------------
// MARK: - View Lifecycle
//-------------------------------------------------------
open override func setupView() {
super.setupView()
headlineBody.styleLandingPageHeader()
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? HeadersH1ButtonModel else { return }
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
buttons.set(with: model.buttons, delegateObject, additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 121
}
open override func reset() {
super.reset()
headlineBody.styleLandingPageHeader()
}
}

View File

@ -0,0 +1,54 @@
//
// HeadersH1ButtonModel.swift
// MVMCoreUI
//
// Created by Lekshmi S on 04/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class HeadersH1ButtonModel: HeaderModel, MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "headerH1Btn"
public var headlineBody: HeadlineBodyModel
public var buttons: TwoButtonViewModel
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(headlineBody: HeadlineBodyModel, buttons: TwoButtonViewModel) {
self.headlineBody = headlineBody
self.buttons = buttons
super.init()
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case headlineBody
case buttons
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody)
buttons = try typeContainer.decode(TwoButtonViewModel.self, forKey: .buttons)
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(headlineBody, forKey: .headlineBody)
try container.encode(buttons, forKey: .buttons)
}
}

View File

@ -0,0 +1,71 @@
//
// HeadersH1LandingPageHeader.swift
// MVMCoreUI
//
// Created by Lekshmi S on 09/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class HeadersH1LandingPageHeader: HeaderView {
//--------------------------------------------------
// MARK: - Outlets
//--------------------------------------------------
public let headline = Label(fontStyle: .Title2XLarge)
public let headline2 = Label(fontStyle: .Title2XLarge)
public let subHeadline = Label(fontStyle: .BoldBodySmall)
public let body = Label(fontStyle: .RegularBodySmall)
public let link = Link()
public let buttons = TwoButtonView(frame: .zero)
public var stack: Stack<StackModel>!
//--------------------------------------------------
// MARK: - Constants
//--------------------------------------------------
let spacingBetweenHeadlineHeadline2: CGFloat = 16.0
let spacingBetweenHeadline2subHeadline: CGFloat = 32.0
let spacingBetweenSubHeadlineBodyLink: CGFloat = 8.0
let spacingBetweenLinkButtons: CGFloat = 128.0
//-------------------------------------------------------
// MARK: - View Lifecycle
//-------------------------------------------------------
open override func setupView() {
super.setupView()
stack = Stack<StackModel>.createStack(with: [(view: headline, model: StackItemModel()),
(view: headline2, model: StackItemModel(spacing: spacingBetweenHeadlineHeadline2)),
(view: subHeadline, model: StackItemModel(spacing: spacingBetweenHeadline2subHeadline)),
(view: body, model: StackItemModel(spacing: spacingBetweenSubHeadlineBodyLink)),
(view: link, model: StackItemModel(spacing: spacingBetweenSubHeadlineBodyLink, horizontalAlignment: .leading)),
(view: buttons, model: StackItemModel(spacing: spacingBetweenLinkButtons))])
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? HeadersH1LandingPageHeaderModel else { return }
headline.set(with: model.headline, delegateObject, additionalData)
headline2.set(with: model.headline2, delegateObject, additionalData)
subHeadline.set(with: model.subHeadline, delegateObject, additionalData)
body.set(with: model.body, delegateObject, additionalData)
link.set(with: model.link, delegateObject, additionalData)
buttons.set(with: model.buttons, delegateObject, additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 121
}
open override func reset() {
super.reset()
headline.setFontStyle(.Title2XLarge)
headline2.setFontStyle(.Title2XLarge)
subHeadline.setFontStyle(.BoldBodySmall)
body.setFontStyle(.RegularBodySmall)
}
}

View File

@ -0,0 +1,74 @@
//
// HeadersH1LandingPageHeaderModel.swift
// MVMCoreUI
//
// Created by Lekshmi S on 09/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class HeadersH1LandingPageHeaderModel: HeaderModel, MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "headerH1Landing"
public var headline: LabelModel
public var headline2: LabelModel
public var subHeadline: LabelModel
public var body: LabelModel
public var link: LinkModel
public var buttons: TwoButtonViewModel
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(headline: LabelModel, headline2: LabelModel, subHeadline: LabelModel, body: LabelModel, link: LinkModel, buttons: TwoButtonViewModel) {
self.headline = headline
self.headline2 = headline2
self.subHeadline = subHeadline
self.body = body
self.link = link
self.buttons = buttons
super.init()
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case headline
case headline2
case subHeadline
case body
case link
case buttons
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
headline = try typeContainer.decode(LabelModel.self, forKey: .headline)
headline2 = try typeContainer.decode(LabelModel.self, forKey: .headline2)
subHeadline = try typeContainer.decode(LabelModel.self, forKey: .subHeadline)
body = try typeContainer.decode(LabelModel.self, forKey: .body)
link = try typeContainer.decode(LinkModel.self, forKey: .link)
buttons = try typeContainer.decode(TwoButtonViewModel.self, forKey: .buttons)
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(headline, forKey: .headline)
try container.encode(headline2, forKey: .headline2)
try container.encode(subHeadline, forKey: .subHeadline)
try container.encode(body, forKey: .body)
try container.encode(link, forKey: .link)
try container.encode(buttons, forKey: .buttons)
}
}

View File

@ -33,9 +33,13 @@ public class HeadersH2ButtonsModel: HeaderModel, MoleculeModelProtocol {
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
super.setDefaults()
topPadding = PaddingDefaultVerticalSpacing3
bottomPadding = PaddingDefaultVerticalSpacing3
}
//--------------------------------------------------

View File

@ -0,0 +1,59 @@
//
// HeadersH2Link.swift
// MVMCoreUI
//
// Created by Lekshmi S on 24/06/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class HeadersH2Link: HeaderView {
//--------------------------------------------------
// MARK: - Outlets
//--------------------------------------------------
public let headlineBody = HeadlineBody()
public let link = Link()
public let stack: Stack<StackModel>
//-------------------------------------------------------
// MARK: - Initializers
//-------------------------------------------------------
public override init(frame: CGRect) {
stack = Stack<StackModel>.createStack(with: [headlineBody, link])
super.init(frame: frame)
}
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//-------------------------------------------------------
// MARK: - Lifecycle
//-------------------------------------------------------
open override func setupView() {
super.setupView()
headlineBody.stylePageHeader()
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? HeadersH2LinkModel else { return }
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
link.set(with: model.link, delegateObject, additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 121
}
open override func reset() {
super.reset()
headlineBody.stylePageHeader()
}
}

View File

@ -0,0 +1,72 @@
//
// HeadersH2LinkModel.swift
// MVMCoreUI
//
// Created by Lekshmi S on 24/06/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class HeadersH2LinkModel: HeaderModel, MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "headerH2Link"
public var headlineBody: HeadlineBodyModel
public var link: LinkModel
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(headlineBody: HeadlineBodyModel, link: LinkModel) {
self.headlineBody = headlineBody
self.link = link
super.init()
}
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
super.setDefaults()
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case headlineBody
case link
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody)
link = try typeContainer.decode(LinkModel.self, forKey: .link)
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(headlineBody, forKey: .headlineBody)
try container.encode(link, forKey: .link)
}
}

View File

@ -27,9 +27,13 @@ public class HeadersH2NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol
}
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
super.setDefaults()
topPadding = PaddingDefaultVerticalSpacing3
bottomPadding = PaddingDefaultVerticalSpacing3
}
//--------------------------------------------------

View File

@ -0,0 +1,121 @@
//
// HeadersH2PricingTwoRows.swift
// MVMCoreUI
//
// Created by Lekshmi S on 16/06/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class HeadersH2PricingTwoRows: HeaderView {
//--------------------------------------------------
// MARK: - Outlets
//--------------------------------------------------
public let headline = Label(fontStyle: .RegularTitleLarge)
public let body = Label(fontStyle: .RegularMicro)
public let subBody = Label(fontStyle: .RegularMicro)
public let body2 = Label(fontStyle: .RegularMicro)
public let subBody2 = Label(fontStyle: .RegularMicro)
public let body3 = Label(fontStyle: .RegularMicro)
public let subBody3 = Label(fontStyle: .RegularMicro)
public let verticalLine1 = Line()
public let verticalLine2 = Line()
public let verticalStack1: Stack<StackModel>
public let verticalStack2: Stack<StackModel>
public let verticalStack3: Stack<StackModel>
public let horizontalStack: Stack<StackModel>
public let stack: Stack<StackModel>
//-------------------------------------------------------
// MARK: - Initializers
//-------------------------------------------------------
public override init(frame: CGRect) {
verticalStack1 = Stack<StackModel>.createStack(with: [body, subBody], spacing: 0)
verticalStack2 = Stack<StackModel>.createStack(with: [body2, subBody2], spacing: 0)
verticalStack3 = Stack<StackModel>.createStack(with: [body3, subBody3], spacing: 0)
horizontalStack = Stack<StackModel>.createStack(with: [(view: verticalStack1, model: StackItemModel(percent: 29, verticalAlignment: .top)), (view: verticalLine1, model: StackItemModel(verticalAlignment: .top)),
(view: verticalStack2, model: StackItemModel(horizontalAlignment: .leading, verticalAlignment: .top)),
(view: verticalLine2, model: StackItemModel(verticalAlignment: .top)),
(view: verticalStack3, model: StackItemModel(percent: 32, verticalAlignment: .top))],
axis: .horizontal)
stack = Stack<StackModel>.createStack(with: [headline, horizontalStack], spacing: 8)
super.init(frame: frame)
}
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//-------------------------------------------------------
// MARK: - Lifecycle
//-------------------------------------------------------
open override func setupView() {
super.setupView()
setDefaults()
body.numberOfLines = 1
body.lineBreakMode = .byTruncatingTail
body2.numberOfLines = 1
body2.lineBreakMode = .byTruncatingTail
body3.numberOfLines = 1
body3.lineBreakMode = .byTruncatingTail
verticalLine1.widthConstraint?.isActive = true
verticalLine1.backgroundColor = .mvmBlack
verticalLine2.widthConstraint?.isActive = true
verticalLine2.backgroundColor = .mvmBlack
addMolecule(stack)
stack.restack()
verticalStack1.restack()
verticalStack2.restack()
verticalStack3.restack()
horizontalStack.restack()
setLineHeight()
}
open func setDefaults() {
headline.setFontStyle(.BoldTitleLarge)
body.setFontStyle(.RegularMicro)
subBody.setFontStyle(.RegularMicro)
body2.setFontStyle(.RegularMicro)
subBody2.setFontStyle(.RegularMicro)
body3.setFontStyle(.RegularMicro)
subBody3.setFontStyle(.RegularMicro)
subBody.textColor = .mvmCoolGray6
subBody2.textColor = .mvmCoolGray6
subBody3.textColor = .mvmCoolGray6
}
open func setLineHeight() {
verticalLine1.heightConstraint?.isActive = false
verticalLine1.heightConstraint = verticalLine1.heightAnchor.constraint(equalTo: body2.heightAnchor, multiplier: 1)
verticalLine1.heightConstraint?.isActive = true
verticalLine2.heightConstraint?.isActive = false
verticalLine2.heightConstraint = verticalLine2.heightAnchor.constraint(equalTo: body3.heightAnchor, multiplier: 1)
verticalLine2.heightConstraint?.isActive = true
}
//----------------------------------------------------
// 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? HeadersH2PricingTwoRowsModel else { return }
headline.set(with: model.headline, delegateObject, additionalData)
verticalStack1.updateContainedMolecules(with: [model.body, model.subBody], delegateObject, additionalData)
verticalStack2.updateContainedMolecules(with: [model.body2, model.subBody2], delegateObject, additionalData)
verticalStack3.updateContainedMolecules(with: [model.body3, model.subBody3], delegateObject, additionalData)
setLineHeight()
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 121
}
open override func reset() {
super.reset()
setDefaults()
}
}

View File

@ -0,0 +1,95 @@
//
// HeadersH2PricingTwoRowsModel.swift
// MVMCoreUI
//
// Created by Lekshmi S on 16/06/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class HeadersH2PricingTwoRowsModel: HeaderModel, MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "headerH2TwoRows"
public var headline: LabelModel
public var body: LabelModel
public var subBody: LabelModel?
public var body2: LabelModel
public var subBody2: LabelModel?
public var body3: LabelModel
public var subBody3: LabelModel?
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(headline: LabelModel, body: LabelModel, subBody: LabelModel? = nil, body2: LabelModel, subBody2: LabelModel? = nil, body3: LabelModel, subBody3: LabelModel? = nil) {
self.headline = headline
self.body = body
self.subBody = subBody
self.body2 = body2
self.subBody2 = subBody2
self.body3 = body3
self.subBody3 = subBody3
super.init()
}
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
super.setDefaults()
subBody?.attributes = [LabelAttributeStrikeThroughModel(0, subBody?.text.count ?? 0)]
subBody2?.attributes = [LabelAttributeStrikeThroughModel(0, subBody2?.text.count ?? 0)]
subBody3?.attributes = [LabelAttributeStrikeThroughModel(0, subBody3?.text.count ?? 0)]
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case headline
case body
case subBody
case body2
case subBody2
case body3
case subBody3
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
headline = try typeContainer.decode(LabelModel.self, forKey: .headline)
body = try typeContainer.decode(LabelModel.self, forKey: .body)
subBody = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .subBody)
body2 = try typeContainer.decode(LabelModel.self, forKey: .body2)
subBody2 = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .subBody2)
body3 = try typeContainer.decode(LabelModel.self, forKey: .body3)
subBody3 = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .subBody3)
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(headline, forKey: .headline)
try container.encode(body, forKey: .body)
try container.encodeIfPresent(subBody, forKey: .subBody)
try container.encode(body2, forKey: .body2)
try container.encodeIfPresent(subBody2, forKey: .subBody2)
try container.encode(body3, forKey: .body3)
try container.encodeIfPresent(subBody3, forKey: .subBody3)
}
}

View File

@ -33,9 +33,13 @@ public class HeadersH2TinyButtonModel: HeaderModel, MoleculeModelProtocol {
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
super.setDefaults()
topPadding = PaddingDefaultVerticalSpacing3
bottomPadding = PaddingDefaultVerticalSpacing3
button.style = .secondary
button.size = .tiny
}

View File

@ -58,10 +58,8 @@ import Foundation
addMolecule(stack)
stack.restack()
verticalStack.restack()
isAccessibilityElement = true
accessibilityTraits = button.accessibilityTraits
accessibilityHint = button.accessibilityHint
updateAccessibilityLabel()
accessibilityTraits = button.accessibilityTraits
}
//--------------------------------------------------
@ -100,10 +98,8 @@ import Foundation
// MARK: - Accessibility
//--------------------------------------------------
func updateAccessibilityLabel() {
func getAccessibilityMessage() -> String? {
var message = ""
if let eyebrowText = eyebrow.text, !eyebrowText.isEmpty {
message += eyebrowText + ", "
}
@ -120,11 +116,28 @@ import Foundation
message += body2Text + ", "
}
if let rightImageViewText = rightImageView.accessibilityLabel, !rightImageViewText.isEmpty {
if let rightImageViewText = rightImageView.imageView.accessibilityLabel, !rightImageViewText.isEmpty {
message += rightImageViewText
}
accessibilityLabel = message
return message.count > 0 ? message : nil
}
func updateAccessibilityLabel() {
if let accessoryView = accessoryView {
// Both caret and button. Read all content on caret.
isAccessibilityElement = false
accessoryView.accessibilityLabel = getAccessibilityMessage()
accessibilityElements = [accessoryView, button]
} else {
// Make whole cell focusable if no action.
isAccessibilityElement = true
if let message = getAccessibilityMessage(),
let buttonTitle = button.titleLabel?.text {
accessibilityLabel = message + ", " + buttonTitle
} else {
accessibilityLabel = getAccessibilityMessage()
}
}
}
open override func accessibilityActivate() -> Bool {

View File

@ -58,10 +58,8 @@ import Foundation
addMolecule(stack)
stack.restack()
verticalStack.restack()
isAccessibilityElement = true
accessibilityTraits = button.accessibilityTraits
accessibilityHint = button.accessibilityHint
updateAccessibilityLabel()
accessibilityTraits = button.accessibilityTraits
}
//--------------------------------------------------
@ -100,10 +98,8 @@ import Foundation
// MARK: - Accessibility
//--------------------------------------------------
func updateAccessibilityLabel() {
func getAccessibilityMessage() -> String? {
var message = ""
if let eyebrowText = eyebrow.text, !eyebrowText.isEmpty {
message += eyebrowText + ", "
}
@ -120,11 +116,28 @@ import Foundation
message += body2Text + ", "
}
if let rightImageViewText = rightImageView.accessibilityLabel, !rightImageViewText.isEmpty {
if let rightImageViewText = rightImageView.imageView.accessibilityLabel, !rightImageViewText.isEmpty {
message += rightImageViewText
}
accessibilityLabel = message
return message.count > 0 ? message : nil
}
func updateAccessibilityLabel() {
if let accessoryView = accessoryView {
// Both caret and button. Read all content on caret.
isAccessibilityElement = false
accessoryView.accessibilityLabel = getAccessibilityMessage()
accessibilityElements = [accessoryView, button]
} else {
// Make whole cell focusable if no action.
isAccessibilityElement = true
if let message = getAccessibilityMessage(),
let buttonTitle = button.titleLabel?.text {
accessibilityLabel = message + ", " + buttonTitle
} else {
accessibilityLabel = getAccessibilityMessage()
}
}
}
open override func accessibilityActivate() -> Bool {

View File

@ -114,7 +114,7 @@ import Foundation
message += body2Text + ", "
}
if let rightImageLabel = rightImage.accessibilityLabel, !rightImageLabel.isEmpty {
if let rightImageLabel = rightImage.imageView.accessibilityLabel, !rightImageLabel.isEmpty {
message += rightImageLabel
}
@ -145,8 +145,8 @@ import Foundation
views.append(twoLinkView.leftLink)
views.append(twoLinkView.rightLink)
if let rightImageLabel = rightImage.accessibilityLabel, !rightImageLabel.isEmpty {
views.append(rightImage)
if let rightImageLabel = rightImage.imageView.accessibilityLabel, !rightImageLabel.isEmpty {
views.append(rightImage.imageView)
}
accessibilityElements = views

View File

@ -111,7 +111,7 @@ import Foundation
message += body2Text + ", "
}
if let rightImageLabel = rightImage.accessibilityLabel, !rightImageLabel.isEmpty {
if let rightImageLabel = rightImage.imageView.accessibilityLabel, !rightImageLabel.isEmpty {
message += rightImageLabel
}
@ -142,8 +142,8 @@ import Foundation
views.append(twoLinkView.leftLink)
views.append(twoLinkView.rightLink)
if let rightImageLabel = rightImage.accessibilityLabel, !rightImageLabel.isEmpty {
views.append(rightImage)
if let rightImageLabel = rightImage.imageView.accessibilityLabel, !rightImageLabel.isEmpty {
views.append(rightImage.imageView)
}
accessibilityElements = views

View File

@ -54,8 +54,6 @@ import Foundation
arrow.pinHeightAndWidth()
arrowAndLabel2Stack.restack()
stack.restack()
isAccessibilityElement = true
updateAccessibilityLabel()
}
//-----------------------------------------------------
@ -92,7 +90,7 @@ import Foundation
//-----------------------------------------------------
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let label1Text = label1.text, !label1Text.isEmpty {

View File

@ -49,11 +49,9 @@ import Foundation
addMolecule(stack)
stack.restack()
isAccessibilityElement = true
checkbox.isAccessibilityElement = false
accessibilityTraits = checkbox.accessibilityTraits
accessibilityHint = checkbox.accessibilityHint
// Update accessibility label on radio button state change.
accessibilityTraits = checkbox.accessibilityTraits
// Update accessibility label on checkbox state change.
observation = observe(\.checkbox.isSelected, options: [.new]) { [weak self] _, _ in
self?.updateAccessibilityLabel()
}
@ -92,41 +90,19 @@ import Foundation
message += checkboxLabel + ", "
}
if let eyebrowLabel = eyebrowHeadlineBodyLink.eyebrow.text, !eyebrowLabel.isEmpty {
message += eyebrowLabel + ", "
}
if let headlineLabel = eyebrowHeadlineBodyLink.headline.text, !headlineLabel.isEmpty {
message += headlineLabel + ", "
}
if let bodyLabel = eyebrowHeadlineBodyLink.body.text, !bodyLabel.isEmpty {
message += bodyLabel
if let label = eyebrowHeadlineBodyLink.getAccessibilityMessage() {
message += label
}
let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0
isAccessibilityElement = !linkShowing
checkbox.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.
// Allow only checkbox and link to be focused on.
checkbox.accessibilityLabel = message
var elements: [UIView] = []
if message.count > 0 {
elements.append(checkbox)
}
if linkShowing {
elements.append(eyebrowHeadlineBodyLink.link)
}
accessibilityElements = elements
accessibilityElements = [checkbox, eyebrowHeadlineBodyLink.link]
}
}

View File

@ -49,10 +49,9 @@ import Foundation
addMolecule(stack)
stack.restack()
isAccessibilityElement = true
checkbox.isAccessibilityElement = false
accessibilityTraits = checkbox.accessibilityTraits
accessibilityHint = checkbox.accessibilityHint
// Update accessibility label on radio button state change.
accessibilityTraits = checkbox.accessibilityTraits
// Update accessibility label on checkbox state change.
observation = observe(\.checkbox.isSelected, options: [.new]) { [weak self] _, _ in
self?.updateAccessibilityLabel()
}

View File

@ -42,7 +42,6 @@ import Foundation
leftImage.imageView.contentMode = .scaleAspectFit
addMolecule(stack)
stack.restack()
updateAccessibilityLabel()
}
//--------------------------------------------------
@ -63,57 +62,37 @@ import Foundation
return 140
}
func getAccessibilityMessage() -> String? {
guard let leftImageLabel = leftImage.imageView.accessibilityLabel else {
return eyebrowHeadlineBodyLink.getAccessibilityMessage()
}
guard let label = eyebrowHeadlineBodyLink.getAccessibilityMessage() else {
return leftImageLabel
}
return leftImageLabel + ", " + label
}
func updateAccessibilityLabel() {
var message = ""
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
}
let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0
isAccessibilityElement = !linkShowing
eyebrowHeadlineBodyLink.link.isAccessibilityElement = linkShowing
accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none
if !linkShowing {
// Make whole cell focusable if no link.
accessibilityLabel = message
accessibilityLabel = getAccessibilityMessage()
} else if let accessoryView = accessoryView {
// Both caret and link. Read all content on caret.
accessoryView.accessibilityLabel = getAccessibilityMessage()
accessibilityElements = [accessoryView, eyebrowHeadlineBodyLink.link]
} else {
// Allow only radio button and link to be focused on.
var elements: [UIView] = []
if let leftImageLabel = leftImage.accessibilityLabel, !leftImageLabel.isEmpty {
elements.append(leftImage)
// Only link. Manually add accessibility elements to ensure they are read in the right order.
var elements: [Any] = []
if let leftImageLabel = leftImage.imageView.accessibilityLabel, !leftImageLabel.isEmpty {
elements.append(leftImage.imageView)
}
if let eyeBrowText = eyebrowHeadlineBodyLink.eyebrow.text, !eyeBrowText.isEmpty {
elements.append(eyebrowHeadlineBodyLink.eyebrow)
if let otherElements = eyebrowHeadlineBodyLink.getAccessibilityElements() {
elements.append(otherElements)
}
if let headlineText = eyebrowHeadlineBodyLink.headline.text, !headlineText.isEmpty {
elements.append(eyebrowHeadlineBodyLink.headline)
}
if let bodyText = eyebrowHeadlineBodyLink.body.text, !bodyText.isEmpty {
elements.append(eyebrowHeadlineBodyLink.body)
}
if linkShowing {
elements.append(eyebrowHeadlineBodyLink.link)
}
accessibilityElements = elements
}
}

View File

@ -48,8 +48,6 @@ import UIKit
rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 902), for: .horizontal)
addMolecule(stack)
stack.restack()
isAccessibilityElement = true
updateAccessibilityLabel()
}
//--------------------------------------------------
@ -78,10 +76,10 @@ import UIKit
}
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let leftImageLabel = leftImage.accessibilityLabel {
if let leftImageLabel = leftImage.imageView.accessibilityLabel {
message += leftImageLabel + ", "
}
@ -94,5 +92,6 @@ import UIKit
}
accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none
}
}

View File

@ -58,10 +58,8 @@ import Foundation
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal)
rightLabel.numberOfLines = 1
isAccessibilityElement = true
addMolecule(stack)
stack.restack()
updateAccessibilityLabel()
}
//--------------------------------------------------
@ -93,10 +91,10 @@ import Foundation
//--------------------------------------------------
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let leftImageLabel = leftImage.accessibilityLabel {
if let leftImageLabel = leftImage.imageView.accessibilityLabel {
message += leftImageLabel + ", "
}
@ -113,5 +111,6 @@ import Foundation
}
accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none
}
}

View File

@ -37,10 +37,11 @@ import Foundation
//--------------------------------------------------
override open func setupView() {
super.setupView()
leftLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
leftLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
leftLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
addMolecule(stack)
stack.restack()
updateAccessibilityLabel()
}
//---------------------------------------------------
@ -66,66 +67,41 @@ import Foundation
leftLabel.setFontStyle(.Title2XLarge)
}
open override func layoutSubviews() {
super.layoutSubviews()
// This fixes a defect body text where it doesn't layout correctly.
eyebrowHeadlineBodyLink.body.preferredMaxLayoutWidth = eyebrowHeadlineBodyLink.frame.width
}
//--------------------------------------------------
// MARK: - Accessibility
//--------------------------------------------------
func getAccessibilityMessage() -> String? {
guard let leftLabel = leftLabel.text else {
return eyebrowHeadlineBodyLink.getAccessibilityMessage()
}
guard let label = eyebrowHeadlineBodyLink.getAccessibilityMessage() else {
return leftLabel
}
return leftLabel + ", " + label
}
func updateAccessibilityLabel() {
var message = ""
if let leftLabel = leftLabel.text {
message += leftLabel + ", "
}
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
eyebrowHeadlineBodyLink.link.isAccessibilityElement = linkShowing
accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none
if !linkShowing {
// Make whole cell focusable if no link.
accessibilityLabel = message
accessibilityLabel = getAccessibilityMessage()
} else if let accessoryView = accessoryView {
// Both caret and link. Read all content on caret.
accessoryView.accessibilityLabel = getAccessibilityMessage()
accessibilityElements = [accessoryView, eyebrowHeadlineBodyLink.link]
} else {
var elements: [UIView] = []
// Only link. Manually add accessibility elements to ensure they are read in the right order.
var elements: [Any] = []
if let leftLabelText = leftLabel.text, !leftLabelText.isEmpty {
elements.append(leftLabel)
}
if let eyeBrowText = eyebrowHeadlineBodyLink.eyebrow.text, !eyeBrowText.isEmpty {
elements.append(eyebrowHeadlineBodyLink.eyebrow)
if let otherElements = eyebrowHeadlineBodyLink.getAccessibilityElements() {
elements.append(otherElements)
}
if let headlineText = eyebrowHeadlineBodyLink.headline.text, !headlineText.isEmpty {
elements.append(eyebrowHeadlineBodyLink.headline)
}
if let bodyText = eyebrowHeadlineBodyLink.body.text, !bodyText.isEmpty {
elements.append(eyebrowHeadlineBodyLink.body)
}
if linkShowing {
elements.append(eyebrowHeadlineBodyLink.link)
}
accessibilityElements = elements
}
}

View File

@ -0,0 +1,95 @@
//
// ListLeftVariableNumberedListBodyText.swift
// MVMCoreUI
//
// Created by Subhankar Acharya on 12/06/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class ListLeftVariableNumberedListBodyText: TableViewCell {
//--------------------------------------------------
// MARK: - Outlets
//-----------------------------------------------------
public let leftLabel = Label(fontStyle: .Title2XLarge)
public let headlineBody = HeadlineBody()
public var stack: Stack<StackModel>
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
stack = Stack<StackModel>.createStack(with: [(view: leftLabel, model: StackItemModel(horizontalAlignment: .fill)),
(view: headlineBody, 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: - Life Cycle
//--------------------------------------------------
override open func setupView() {
super.setupView()
leftLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
leftLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
leftLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
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? ListLeftVariableNumberedListBodyTextModel else { return }
leftLabel.text = String(model.number)
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
updateAccessibilityLabel()
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 140
}
open override func reset() {
super.reset()
leftLabel.setFontStyle(.Title2XLarge)
}
//--------------------------------------------------
// MARK: - Accessibility
//--------------------------------------------------
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let leftLabel = leftLabel.text {
message += leftLabel + ", "
}
if let headlineLabel = headlineBody.headlineLabel.text {
message += headlineLabel + ", "
}
if let messageLabel = headlineBody.messageLabel.text {
message += messageLabel
}
accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none
}
}

View File

@ -0,0 +1,58 @@
//
// ListLeftVariableNumberedListBodyTextModel.swift
// MVMCoreUI
//
// Created by Subhankar Acharya on 12/06/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class ListLeftVariableNumberedListBodyTextModel: ListItemModel, MoleculeModelProtocol {
//-----------------------------------------------------
// MARK: - Properties
//-----------------------------------------------------
public static var identifier: String = "listLVNLBdy"
public var number: Int
public var headlineBody: HeadlineBodyModel
//-----------------------------------------------------
// MARK: - Initializer
//-----------------------------------------------------
public init(number: Int, headlineBody: HeadlineBodyModel) {
self.number = number
self.headlineBody = headlineBody
super.init()
}
//-----------------------------------------------------
// MARK: - Keys
//-----------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case number
case headlineBody
}
//-----------------------------------------------------
// MARK: - Codec
//-----------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
number = try typeContainer.decode(Int.self, forKey: .number)
headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody)
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(number, forKey: .number)
try container.encode(headlineBody, forKey: .headlineBody)
}
}

View File

@ -89,41 +89,19 @@ import Foundation
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
if let label = eyebrowHeadlineBodyLink.getAccessibilityMessage() {
message += label
}
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.isEmpty {
elements.append(radioButton)
}
if linkShowing {
elements.append(eyebrowHeadlineBodyLink.link)
}
accessibilityElements = elements
accessibilityElements = [radioButton, eyebrowHeadlineBodyLink.link]
}
}
}

View File

@ -50,9 +50,9 @@ import UIKit
eyebrowHeadlineBodyLink.body.textColor = .mvmOrangeAA
eyebrowHeadlineBodyLink.headline.setFontStyle(.BoldBodySmall)
accessibilityTraits = radioButton.accessibilityTraits
accessibilityHint = radioButton.accessibilityHint
accessibilityTraits = radioButton.accessibilityTraits
// Update accessibility label on radio button state change.
observation = observe(\.radioButton.isSelected, options: [.new]) { [weak self] _, _ in
self?.updateAccessibilityLabel()
@ -103,44 +103,23 @@ import UIKit
message += radioButtonLabel + ", "
}
if let leftImageLabel = leftImage.accessibilityLabel {
if let leftImageLabel = leftImage.imageView.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
if let label = eyebrowHeadlineBodyLink.getAccessibilityMessage() {
message += label
}
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.isEmpty {
elements.append(radioButton)
}
if linkShowing {
elements.append(eyebrowHeadlineBodyLink.link)
}
accessibilityElements = elements
accessibilityElements = [radioButton, eyebrowHeadlineBodyLink.link]
}
}
}

View File

@ -47,9 +47,8 @@ open class ListLeftVariableRadioButtonBodyText: TableViewCell {
// Make the whole cell focusable.
isAccessibilityElement = true
radioButton.isAccessibilityElement = false
accessibilityTraits = radioButton.accessibilityTraits
accessibilityHint = radioButton.accessibilityHint
accessibilityTraits = radioButton.accessibilityTraits
updateAccessibilityLabel()
// Update accessibility label on radio button state change.

View File

@ -78,8 +78,6 @@ import Foundation
stack.restack()
horizontalStack.restack()
labelStack.restack()
isAccessibilityElement = true
updateAccessibilityLabel()
}
//------------------------------------------------------
@ -115,7 +113,7 @@ import Foundation
//------------------------------------------------------
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let leftHeadlineText = leftHeadline.text {
@ -135,5 +133,6 @@ import Foundation
}
accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none
}
}

View File

@ -43,7 +43,6 @@ import Foundation
super.setupView()
addMolecule(stack)
stack.restack()
updateAccessibilityLabel()
}
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
@ -72,8 +71,7 @@ import Foundation
// MARK: - Accessibility
//--------------------------------------------------
func updateAccessibilityLabel() {
func getAccessibilityMessage() -> String? {
var message = ""
if let eyebrowLabel = eyebrow.text, !eyebrowLabel.isEmpty {
@ -91,19 +89,31 @@ import Foundation
if let bodyLabel = body.text, !bodyLabel.isEmpty {
message += bodyLabel
}
return message.count > 0 ? message : nil
}
// Ensures voice over does not read "selected" after user triggers action on cell.
override public var accessibilityTraits: UIAccessibilityTraits {
get {
return (accessoryView != nil) ? .button : .none
}
set {}
}
func updateAccessibilityLabel() {
let linkShowing = link.titleLabel?.text?.count ?? 0 > 0
isAccessibilityElement = !linkShowing
link.isAccessibilityElement = linkShowing
if !linkShowing {
// Make whole cell focusable if no link.
accessibilityLabel = message
accessibilityLabel = getAccessibilityMessage()
} else if let accessoryView = accessoryView {
// Both caret and link. Read all content on caret.
accessoryView.accessibilityLabel = getAccessibilityMessage()
accessibilityElements = [accessoryView, link]
} else {
// Allow only radio button and link to be focused on.
var elements: [UIView] = []
// Only link. Manually add accessibility elements to ensure they are read in the right order.
var elements: [Any] = []
if let eyeBrowText = eyebrow.text, !eyeBrowText.isEmpty {
elements.append(eyebrow)
}
@ -119,11 +129,7 @@ import Foundation
if let bodyText = body.text, !bodyText.isEmpty {
elements.append(body)
}
if linkShowing {
elements.append(link)
}
elements.append(link)
accessibilityElements = elements
}
}

View File

@ -24,8 +24,6 @@ import Foundation
super.setupView()
addMolecule(headlineBody)
isAccessibilityElement = true
updateAccessibilityLabel()
}
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?){
@ -46,7 +44,7 @@ import Foundation
//-----------------------------------------------------
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let headlineLabel = headlineBody.headlineLabel.text {

View File

@ -41,8 +41,6 @@ import Foundation
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
addMolecule(stack)
stack.restack()
isAccessibilityElement = true
updateAccessibilityLabel()
}
//-------------------------------------------------
@ -75,7 +73,7 @@ import Foundation
//--------------------------------------------------
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let leftLabelText = leftLabel.text, !leftLabelText.isEmpty {
@ -91,5 +89,6 @@ import Foundation
}
accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none
}
}

View File

@ -47,9 +47,9 @@ import Foundation
addMolecule(stack)
stack.restack()
updateAccessibilityLabel()
accessibilityValue = button.accessibilityValue
accessibilityHint = button.accessibilityHint
accessibilityTraits = .button
}
//-----------------------------------------------------
@ -74,48 +74,36 @@ import Foundation
// MARK: - Accessibility
//----------------------------------------------------
func getAccessibilityMessage() -> String? {
guard let buttonText = button.titleLabel?.text else {
return eyebrowHeadlineBodyLink.getAccessibilityMessage()
}
guard let label = eyebrowHeadlineBodyLink.getAccessibilityMessage() else {
return buttonText
}
return label + ", " + buttonText
}
func updateAccessibilityLabel() {
var message = ""
if let eyebrowLabel = eyebrowHeadlineBodyLink.eyebrow.text {
message += eyebrowLabel + ", "
}
if let headlineLabel = eyebrowHeadlineBodyLink.headline.text {
message += headlineLabel + ", "
}
if let bodyLabel = eyebrowHeadlineBodyLink.body.text {
message += bodyLabel + ", "
}
if let buttonLabel = button.accessibilityLabel {
message += buttonLabel
}
let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0
isAccessibilityElement = !linkShowing
button.isAccessibilityElement = linkShowing
eyebrowHeadlineBodyLink.link.isAccessibilityElement = linkShowing
if !linkShowing {
// Make whole cell focusable if no link.
accessibilityLabel = message
if !linkShowing && accessoryView == nil {
// Make whole cell focusable if one action
isAccessibilityElement = true
accessibilityLabel = getAccessibilityMessage()
} else {
// Allow only radio button and link to be focused on.
button.accessibilityLabel = message
var elements: [UIView] = []
if !message.isEmpty {
elements.append(button)
// Make buttons focusable.
isAccessibilityElement = false
var elements: [Any] = []
if let accessoryView = accessoryView {
accessoryView.accessibilityLabel = eyebrowHeadlineBodyLink.getAccessibilityMessage()
elements.append(accessoryView)
} else {
button.accessibilityLabel = getAccessibilityMessage()
}
elements.append(button)
if linkShowing {
elements.append(eyebrowHeadlineBodyLink.link)
}
accessibilityElements = elements
}
}

View File

@ -40,8 +40,6 @@ import Foundation
rightImage.addSizeConstraintsForAspectRatio = true
addMolecule(stack)
stack.restack()
isAccessibilityElement = true
updateAccessibilityLabel()
}
//----------------------------------------------------
@ -72,17 +70,18 @@ import Foundation
//--------------------------------------------------
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let leftLabelText = leftLabel.text, !leftLabelText.isEmpty {
message += leftLabelText + ", "
}
if let rightImageText = rightImage.accessibilityLabel, !rightImageText.isEmpty {
if let rightImageText = rightImage.imageView.accessibilityLabel, !rightImageText.isEmpty {
message += rightImageText
}
accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none
}
}

View File

@ -67,7 +67,6 @@ import Foundation
arrow.pinHeightAndWidth()
addMolecule(stack)
stack.restack()
updateAccessibilityLabel()
}
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
@ -89,57 +88,36 @@ import Foundation
// MARK: - Accessibility
//--------------------------------------------------
func getAccessibilityMessage() -> String? {
guard let rightLabelText = rightLabel.text else {
return eyebrowHeadlineBodyLink.getAccessibilityMessage()
}
guard let label = eyebrowHeadlineBodyLink.getAccessibilityMessage() else {
return rightLabelText
}
return label + ", " + rightLabelText
}
func updateAccessibilityLabel() {
let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0
isAccessibilityElement = !linkShowing
eyebrowHeadlineBodyLink.link.isAccessibilityElement = linkShowing
accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none
if !linkShowing {
// Make whole cell focusable if no link.
var message = ""
if let eyebrowLabel = eyebrowHeadlineBodyLink.eyebrow.text {
message += eyebrowLabel + ", "
}
if let headlineLabel = eyebrowHeadlineBodyLink.headline.text {
message += headlineLabel + ", "
}
if let bodyLabel = eyebrowHeadlineBodyLink.body.text {
message += bodyLabel + ", "
}
if let rightLabelText = rightLabel.text {
message += rightLabelText
}
accessibilityLabel = message
accessibilityLabel = getAccessibilityMessage()
} else if let accessoryView = accessoryView {
// Both caret and link. Read all content on caret.
accessoryView.accessibilityLabel = getAccessibilityMessage()
accessibilityElements = [accessoryView, eyebrowHeadlineBodyLink.link]
} else {
var elements: [UIView] = []
if let eyebrowText = eyebrowHeadlineBodyLink.eyebrow.text, !eyebrowText.isEmpty {
elements.append(eyebrowHeadlineBodyLink.eyebrow)
// Only link. Manually add accessibility elements to ensure they are read in the right order.
var elements: [Any] = []
if let otherElements = eyebrowHeadlineBodyLink.getAccessibilityElements() {
elements.append(otherElements)
}
if let headlineText = eyebrowHeadlineBodyLink.headline.text, !headlineText.isEmpty {
elements.append(eyebrowHeadlineBodyLink.headline)
}
if let bodyText = eyebrowHeadlineBodyLink.body.text, !bodyText.isEmpty {
elements.append(eyebrowHeadlineBodyLink.body)
}
if linkShowing {
elements.append(eyebrowHeadlineBodyLink.link)
}
if let rightLabelText = rightLabel.text, !rightLabelText.isEmpty {
elements.append(rightLabel)
}
accessibilityElements = elements
}
}

View File

@ -54,8 +54,6 @@ import Foundation
addMolecule(stack)
stack.restack()
arrowAndRightLabelStack.restack()
isAccessibilityElement = true
updateAccessibilityLabel()
}
//--------------------------------------------------
@ -87,7 +85,7 @@ import Foundation
//--------------------------------------------------
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let headlineText = headlineBody.headlineLabel.text, !headlineText.isEmpty {
@ -103,5 +101,6 @@ import Foundation
}
accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none
}
}

View File

@ -47,7 +47,6 @@ import Foundation
addMolecule(stack)
stack.restack()
updateAccessibilityLabel()
}
//--------------------------------------------------
@ -72,52 +71,41 @@ import Foundation
// MARK: - Accessibility
//--------------------------------------------------
func getAccessibilityMessage() -> String? {
guard let linkText = link.titleLabel?.text else {
return eyebrowHeadlineBodyLink.getAccessibilityMessage()
}
guard let label = eyebrowHeadlineBodyLink.getAccessibilityMessage() else {
return linkText
}
return label + ", " + linkText
}
func updateAccessibilityLabel() {
var message = ""
if let eyebrowLabel = eyebrowHeadlineBodyLink.eyebrow.text {
message += eyebrowLabel + ", "
}
if let headlineLabel = eyebrowHeadlineBodyLink.headline.text {
message += headlineLabel + ", "
}
if let bodyLabel = eyebrowHeadlineBodyLink.body.text {
message += bodyLabel + ", "
}
if let linkLabel = link.accessibilityLabel {
message += linkLabel
}
let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0
isAccessibilityElement = !linkShowing
link.isAccessibilityElement = linkShowing
eyebrowHeadlineBodyLink.link.isAccessibilityElement = linkShowing
if !linkShowing {
// Make whole cell focusable if no link.
accessibilityLabel = message
accessibilityTraits = .button
if !linkShowing && accessoryView == nil {
// Make whole cell focusable if one action
isAccessibilityElement = true
accessibilityLabel = getAccessibilityMessage()
} else {
// Allow only radio button and link to be focused on.
link.accessibilityLabel = message
var elements: [UIView] = []
// Make buttons focusable.
isAccessibilityElement = false
var elements: [Any] = []
if let accessoryView = accessoryView {
accessoryView.accessibilityLabel = eyebrowHeadlineBodyLink.getAccessibilityMessage()
elements.append(accessoryView)
} else {
link.accessibilityLabel = getAccessibilityMessage()
}
elements.append(link)
if linkShowing {
elements.append(eyebrowHeadlineBodyLink.link)
}
if !message.isEmpty {
elements.append(link)
}
accessibilityElements = elements
}
}
open override func accessibilityActivate() -> Bool {
return link.accessibilityActivate()
}

View File

@ -0,0 +1,114 @@
//
// ListRightVariableToggleAllTextAndLinks.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 6/25/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class ListRightVariableToggleAllTextAndLinks: TableViewCell {
//-----------------------------------------------------
// MARK: - Outlets
//-----------------------------------------------------
public let toggle = Toggle()
public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink()
//-----------------------------------------------------
// MARK: - Properties
//-----------------------------------------------------
public var stack: Stack<StackModel>!
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
stack = Stack<StackModel>.createStack(with: [(view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading)),
(view: toggle, model: StackItemModel(horizontalAlignment: .fill))],
axis: .horizontal)
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//-----------------------------------------------------
// MARK: - Lifecycle
//-----------------------------------------------------
override open func setupView() {
super.setupView()
addMolecule(stack)
stack.restack()
}
//-----------------------------------------------------
// MARK: - Molecular
//-----------------------------------------------------
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? ListRightVariableToggleAllTextAndLinksModel else { return }
toggle.set(with: model.toggle, delegateObject, additionalData)
eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData)
updateAccessibilityLabel()
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 90
}
//----------------------------------------------------
// MARK: - Accessibility
//----------------------------------------------------
func getAccessibilityMessage() -> String? {
guard let toggleMessage = toggle.accessibilityLabel else {
return eyebrowHeadlineBodyLink.getAccessibilityMessage()
}
guard let label = eyebrowHeadlineBodyLink.getAccessibilityMessage() else {
return toggleMessage
}
return label + ", " + toggleMessage
}
func updateAccessibilityLabel() {
accessibilityHint = toggle.accessibilityHint
accessibilityTraits = toggle.accessibilityTraits
accessibilityValue = toggle.accessibilityValue
let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0
if !linkShowing && accessoryView == nil {
// Make whole cell focusable if one action
isAccessibilityElement = true
accessibilityLabel = getAccessibilityMessage()
} else {
// Make buttons focusable.
isAccessibilityElement = false
var elements: [Any] = []
if let accessoryView = accessoryView {
accessoryView.accessibilityLabel = eyebrowHeadlineBodyLink.getAccessibilityMessage()
elements.append(accessoryView)
} else {
toggle.accessibilityLabel = getAccessibilityMessage()
}
elements.append(toggle)
if linkShowing {
elements.append(eyebrowHeadlineBodyLink.link)
}
accessibilityElements = elements
}
}
open override func accessibilityActivate() -> Bool {
let activate = toggle.accessibilityActivate()
accessibilityValue = toggle.accessibilityValue
return activate
}
}

View File

@ -0,0 +1,58 @@
//
// ListRightVariableToggleAllTextAndLinksModel.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 6/25/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class ListRightVariableToggleAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "listRVTgl"
public var toggle: ToggleModel
public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(toggle: ToggleModel, eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel) {
self.toggle = toggle
self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink
super.init()
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case toggle
case eyebrowHeadlineBodyLink
}
//--------------------------------------------------
// MARK: - codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
toggle = try typeContainer.decode(ToggleModel.self, forKey: .toggle)
eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink)
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(toggle, forKey: .toggle)
try container.encode(eyebrowHeadlineBodyLink, forKey: .eyebrowHeadlineBodyLink)
}
}

View File

@ -51,8 +51,6 @@ import Foundation
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
addMolecule(stack)
stack.restack()
isAccessibilityElement = true
updateAccessibilityLabel()
}
//--------------------------------------------------
@ -86,7 +84,7 @@ import Foundation
//--------------------------------------------------
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let leftLabelText = leftLabel.text, !leftLabelText.isEmpty {
@ -98,5 +96,6 @@ import Foundation
}
accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none
}
}

View File

@ -42,8 +42,6 @@ import Foundation
super.setupView()
addMolecule(stack)
stack.restack()
isAccessibilityElement = true
updateAccessibilityLabel()
}
//--------------------------------------------------
@ -77,7 +75,7 @@ import Foundation
//--------------------------------------------------
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let leftText = leftLabel.text, !leftText.isEmpty {

View File

@ -55,8 +55,6 @@ import Foundation
arrow.pinHeightAndWidth()
arrowAndLabel2Stack.restack()
stack.restack()
isAccessibilityElement = true
updateAccessibilityLabel()
}
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
@ -87,7 +85,7 @@ import Foundation
//--------------------------------------------------
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let leftText = leftLabel.text, !leftText.isEmpty {

View File

@ -54,7 +54,6 @@ import Foundation
((molecule as? StackItem)?.view as? Stack<StackModel>)?.restack()
}
containingStack.restack()
isAccessibilityElement = false
}
//------------------------------------------------------

View File

@ -67,9 +67,6 @@ import Foundation
leftHeadline.numberOfLines = 1
rightLabel.numberOfLines = 1
rightSubLabel.numberOfLines = 1
isAccessibilityElement = true
updateAccessibilityLabel()
}
//----------------------------------------------------
@ -107,7 +104,7 @@ import Foundation
//----------------------------------------------------
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let leftHeadline = leftHeadline.text, !leftHeadline.isEmpty {

View File

@ -31,8 +31,6 @@ import UIKit
containerHelper.constrainView(view)
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
rightLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
isAccessibilityElement = true
updateAccessibilityLabel()
}
open override func updateView(_ size: CGFloat) {
@ -72,7 +70,7 @@ import UIKit
//----------------------------------------------------
func updateAccessibilityLabel() {
isAccessibilityElement = true
var message = ""
if let leftLabel = leftLabel.text, !leftLabel.isEmpty {

View File

@ -56,7 +56,7 @@ import Foundation
// Add buttons
var tabs: [UITabBarItem] = []
for (index, tab) in model.tabs.enumerated() {
let tabBarItem = UITabBarItem(title: tab.title, image: UIImage(named: tab.image, in: MVMCoreCache.shared()?.bundleToUseForImages(), compatibleWith: nil), tag: index)
let tabBarItem = UITabBarItem(title: tab.title, image: MVMCoreCache.shared()?.getImageFromRegisteredBundles(tab.image), tag: index)
tabs.append(tabBarItem)
}
setItems(tabs, animated: false)

View File

@ -20,6 +20,7 @@ import Foundation
public var peakingUI: Bool?
public var peakingArrowColor: Color?
public var analyticsData: JSONValueDictionary?
//--------------------------------------------------
// MARK: - Keys
@ -28,6 +29,7 @@ import Foundation
private enum CodingKeys: String, CodingKey {
case peakingUI
case peakingArrowColor
case analyticsData
}
//--------------------------------------------------
@ -38,6 +40,7 @@ import Foundation
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
peakingUI = try typeContainer.decodeIfPresent(Bool.self, forKey: .peakingUI)
peakingArrowColor = try typeContainer.decodeIfPresent(Color.self, forKey: .peakingArrowColor)
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
try super.init(from: decoder)
}
@ -46,5 +49,6 @@ import Foundation
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(peakingUI, forKey: .peakingUI)
try container.encodeIfPresent(peakingArrowColor, forKey: .peakingArrowColor)
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
}
}

View File

@ -11,34 +11,34 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule
public var backgroundColor: Color?
public static var identifier: String = "navigationImageButton"
public var imageName: String
public var image: String
public var action: ActionModelProtocol
public init(with imageName: String, action: ActionModelProtocol) {
self.imageName = imageName
public init(with image: String, action: ActionModelProtocol) {
self.image = image
self.action = action
}
private enum CodingKeys: String, CodingKey {
case imageName
case image
case action
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
imageName = try typeContainer.decode(String.self, forKey: .imageName)
image = try typeContainer.decode(String.self, forKey: .image)
action = try typeContainer.decodeModel(codingKey: .action)
}
open func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(imageName, forKey: .imageName)
try container.encode(image, forKey: .image)
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 {
let image = UIImage(named: imageName, in: MVMCoreCache.shared()?.bundleToUseForImages(), compatibleWith: nil)
return ImageBarButtonItem.create(with: image, actionModel: action, delegateObject: delegateObject, additionalData: additionalData)
let uiImage = MVMCoreCache.shared()?.getImageFromRegisteredBundles(image)
return ImageBarButtonItem.create(with: uiImage, actionModel: action, delegateObject: delegateObject, additionalData: additionalData)
}
}

View File

@ -18,8 +18,8 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt
public var backgroundColor: Color?
public var tintColor: Color
public var line: LineModel?
public var alwaysShowBackButton = false
public var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? = NavigationImageButtonModel(with: "back", action: ActionBackModel())
public var alwaysShowBackButton: Bool?
public var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? = NavigationImageButtonModel(with: "nav_back", action: ActionBackModel())
public var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
public var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
@ -51,8 +51,8 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt
hidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidden) ?? false
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)
alwaysShowBackButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysShowBackButton) ?? false
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) ?? LineModel(type: .standard)
alwaysShowBackButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysShowBackButton)
if let backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol) = try typeContainer.decodeModelIfPresent(codingKey: .backButton) {
self.backButton = backButton
}
@ -68,7 +68,7 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encode(tintColor, forKey: .tintColor)
try container.encodeIfPresent(line, forKey: .line)
try container.encode(alwaysShowBackButton, forKey: .alwaysShowBackButton)
try container.encodeIfPresent(alwaysShowBackButton, forKey: .alwaysShowBackButton)
try container.encodeModelIfPresent(backButton, forKey: .backButton)
try container.encodeModelsIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons)
try container.encodeModelsIfPresent(additionalRightButtons, forKey: .additionalRightButtons)

View File

@ -69,4 +69,44 @@ import UIKit
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 65
}
//--------------------------------------------------
// MARK: - Accessibility Helpers
//--------------------------------------------------
/// Returns the labels text in one message.
func getAccessibilityMessage() -> String? {
var message = ""
if let eyebrowLabel = eyebrow.text {
message += eyebrowLabel + ", "
}
if let headlineLabel = headline.text {
message += headlineLabel + ", "
}
if let bodyLabel = body.text {
message += bodyLabel
}
return message.count > 0 ? message : nil
}
/// Returns an array of the appropriate accessibility elements.
func getAccessibilityElements() -> [Any]? {
var elements: [UIView] = []
if eyebrow.hasText {
elements.append(eyebrow)
}
if headline.hasText {
elements.append(headline)
}
if body.hasText {
elements.append(body)
}
if link.titleLabel?.text?.count ?? 0 > 0 {
elements.append(link)
}
return elements.count > 0 ? elements : nil
}
}

View File

@ -73,8 +73,8 @@ open class ThreeHeadlineBodyLink: View {
bottomAnchor.constraint(equalTo: link.bottomAnchor).isActive = true
isAccessibilityElement = true
accessibilityTraits = link.accessibilityTraits
accessibilityHint = link.accessibilityHint
accessibilityTraits = link.accessibilityTraits
updateAccessibilityLabel()
}

View File

@ -297,6 +297,12 @@ open class Carousel: View {
cell.accessibilityElementsHidden = true
}
}
func trackSwipeActionAnalyticsforIndex(_ index : Int){
guard let itemModel = molecules?[index],
let viewControllerObject = delegateObject?.moleculeDelegate as? MVMCoreViewControllerProtocol else { return }
MVMCoreUILoggingHandler.shared()?.defaultLogAction(forController: viewControllerObject, actionInformation: itemModel.toJSON(), additionalData: nil)
}
}
extension Carousel: UICollectionViewDelegateFlowLayout {
@ -454,5 +460,7 @@ extension Carousel: UIScrollViewDelegate {
// Cycle to other end if on buffer cell.
pagingView?.currentIndex = pageIndex
showPeaking(true)
// track analyticsData
trackSwipeActionAnalyticsforIndex(pageIndex)
}
}

View File

@ -10,4 +10,12 @@ import Foundation
public protocol CarouselItemModelProtocol: ContainerModelProtocol {
var analyticsData: JSONValueDictionary? { get set }
}
public extension CarouselItemModelProtocol {
var analyticsData: JSONValueDictionary? {
get { return nil }
set { analyticsData = newValue }
}
}

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 alwaysShowBackButton: Bool { get set }
var alwaysShowBackButton: Bool? { get set }
var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? { get set }
var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set }
var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]? { get set }

View File

@ -205,8 +205,8 @@ import UIKit
let caret = CaretView(lineWidth: 1)
caret.translatesAutoresizingMaskIntoConstraints = true
caret.isAccessibilityElement = true
caret.accessibilityTraits = .button
caret.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccTabHint")
caret.accessibilityTraits = .button
caret.size = .small(.vertical)
if let size = caret.size?.dimensions() {
caret.frame = CGRect(origin: CGPoint.zero, size: size)

View File

@ -8,7 +8,7 @@
import UIKit
@objc open class ViewController: UIViewController, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MoleculeDelegateProtocol, FormHolderProtocol, MVMCoreActionDelegateProtocol, MVMCoreLoadDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, ObservingTextFieldDelegate {
@objc open class ViewController: UIViewController, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MoleculeDelegateProtocol, FormHolderProtocol, MVMCoreActionDelegateProtocol, MVMCoreLoadDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, ObservingTextFieldDelegate, MVMCoreUIDetailViewProtocol {
@objc public var pageType: String?
@objc public var loadObject: MVMCoreLoadObject?
public var pageModel: MVMControllerModelProtocol?
@ -119,6 +119,7 @@ import UIKit
return true
} catch let parsingError {
// Log all parsing errors and fail load.
handleLoggingFor(parsingError: parsingError)
if let errorObject = MVMCoreErrorObject.createErrorObject(for: parsingError, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject)) {
errorObject.messageToDisplay = MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess)
error.pointee = errorObject
@ -127,6 +128,33 @@ import UIKit
}
}
func handleLoggingFor(parsingError: Error) {
if let registryError = parsingError as? ModelRegistry.Error {
switch (registryError) {
case .decoderErrorModelNotMapped(let identifier, let codingKey, let codingPath) where identifier != nil && codingKey != nil && codingPath != nil:
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Model identifier \"\(identifier!)\" is not mapped for \"\(codingKey!.stringValue)\" @ \(codingPath!.map { return $0.stringValue })")
case .decoderErrorObjectNotPresent(let codingKey, codingPath: let codingPath):
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Required model \"\(codingKey.stringValue)\" was not found @ \(codingPath.map { return $0.stringValue })")
default:
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Registry error: \(registryError)")
}
}
if let decodingError = parsingError as? DecodingError {
switch (decodingError) {
case .keyNotFound(let codingKey, let context):
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })")
case .valueNotFound(_, let context):
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Value not found @ \(context.codingPath.map { return $0.stringValue })")
case .typeMismatch(_, let context):
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Type mismatch @ \(context.codingPath.map { return $0.stringValue })")
case .dataCorrupted(let context):
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Data corrupted @ \(context.codingPath.map { return $0.stringValue })")
@unknown default:
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: \(parsingError)")
}
}
}
open func parsePageJSON() throws {
}
@ -163,9 +191,6 @@ import UIKit
open func createDefaultLegacyNavigationModel() -> NavigationItemModel {
let navigationModel = NavigationItemModel()
navigationModel.title = pageModel?.screenHeading
if /*(self as? MVMCoreUITabBarPageControlViewController) != nil ||*/ manager != nil || loadObject?.requestParameters?.tabWasPressed ?? false == true {
navigationModel.line = LineModel(type: .none)
}
return navigationModel
}
@ -199,18 +224,8 @@ import UIKit
// 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)
// Utilize helper function to set the split view and navigation item state.
MVMCoreUISplitViewController.setSplitViewController(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel, leftPanelAccessible: isMasterInitiallyAccessible(), rightPanelAccessible: isSupportInitiallyAccessible(), progress: bottomProgress() ?? 0)
}
// Eventually will be moved to server
@ -252,12 +267,10 @@ import UIKit
}
// Eventually will be moved to Model
open func showBottomProgressBar() {
if MVMCoreUISplitViewController.main()?.getCurrentVisibleController() == self,
let progressString = loadObject?.pageJSON?.optionalStringForKey(KeyProgressPercent),
let progress = Float(progressString) {
MVMCoreUISplitViewController.main()?.setBottomProgressBarProgress(progress / Float(100))
}
open func bottomProgress() -> Float? {
guard let progressString = loadObject?.pageJSON?.optionalStringForKey(KeyProgressPercent),
let progress = Float(progressString) else { return nil }
return (progress / Float(100))
}
// MARK: - TabBar
@ -321,24 +334,23 @@ import UIKit
super.viewDidLayoutSubviews()
}
open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
open func pageShown() {
// Update the navigation bar ui when view is appearing.
setNavigationController()
// Update the navigation bar ui when view is appearing. Can remove check in the future, see viewControllerReady
if manager == nil {
setNavigationController()
}
// Update tab if needed.
updateTabBar()
// Track.
MVMCoreUISession.sharedGlobal()?.currentPageType = pageType
MVMCoreUILoggingHandler.shared()?.defaultLogPageState(forController: self)
}
open override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Update tab if needed.
updateTabBar()
if manager == nil {
MVMCoreUISession.sharedGlobal()?.currentPageType = pageType
MVMCoreUILoggingHandler.shared()?.defaultLogPageState(forController: self)
pageShown()
}
executeBehaviors { (behavior: PageVisibilityBehavior) in
@ -375,13 +387,7 @@ import UIKit
// MARK: - MVMCoreViewManagerViewControllerProtocol
open func viewControllerReady(inManager manager: UIViewController & MVMCoreViewManagerProtocol) {
// TODO: This check and set aren't technically needed anymore. The one in viewwillappear should be enough. However, there is a timing issue with the manager where the screen lays out before the menu shows, so the screen grows off the screen. Can fix in the future.
if let _ = self.view {
setNavigationController()
}
// Janky way to track current page.
MVMCoreUISession.sharedGlobal()?.currentPageType = pageType
MVMCoreUILoggingHandler.shared()?.defaultLogPageState(forController: self)
pageShown()
}
// MARK: - MVMCoreLoadDelegateProtocol
@ -443,6 +449,13 @@ import UIKit
open func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], indexPath: IndexPath, animation: UITableView.RowAnimation) {}
open func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], animation: UITableView.RowAnimation) {}
// MARK: - MVMCoreUIDetailViewProtocol
// Reset the navigation state.
public func splitViewDidReset() {
setNavigationController()
}
// MARK: - UITextFieldDelegate (Check if this is still needed)
// To Remove TextFields Bug: Keyboard is not dismissing after reaching textfield max length limit
open func textFieldShouldReturn(_ textField: UITextField) -> Bool {

View File

@ -47,13 +47,15 @@ import UIKit
public static func setNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
var leftItems: [UIBarButtonItem] = []
if let backButtonModel = navigationItemModel.backButton,
navigationController.viewControllers.count > 1 || navigationItemModel.alwaysShowBackButton {
leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
}
if let leftItemModels = navigationItemModel.additionalLeftButtons {
for item in leftItemModels {
leftItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
if navigationItemModel.alwaysShowBackButton != false {
if let backButtonModel = navigationItemModel.backButton,
navigationController.viewControllers.count > 1 || navigationItemModel.alwaysShowBackButton ?? false {
leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
}
if let leftItemModels = navigationItemModel.additionalLeftButtons {
for item in leftItemModels {
leftItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
}
}
}
viewController.navigationItem.leftBarButtonItems = leftItems.count > 0 ? leftItems : nil
@ -67,8 +69,8 @@ import UIKit
viewController.navigationItem.rightBarButtonItems = rightItems.count > 0 ? rightItems : nil
}
/// Convenience function for setting navigation bar with model.
public static func set(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
/// Convenience function for setting the navigation bar ui, except for the buttons.
public static func setNavigationUI(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
viewController.navigationItem.title = navigationItemModel.title
viewController.navigationItem.accessibilityLabel = navigationItemModel.title
viewController.navigationItem.hidesBackButton = (navigationItemModel.backButton != nil)
@ -86,8 +88,11 @@ import UIKit
if let navigationController = navigationController as? NavigationController {
navigationController.separatorView?.isHidden = navigationItemModel.line?.type ?? .standard == .none
}
}
// Sets up the navigation buttons.
/// Convenience function for setting navigation bar with model.
public static func set(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
setNavigationUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
}

View File

@ -42,6 +42,9 @@ NS_ASSUME_NONNULL_BEGIN
- (UIStatusBarStyle)defaultStatusBarStyle;
- (nullable UIColor *)defaultStatusBarBackgroundColor;
/// Called when the split view did reset. If this function found, the splitview assumes it is handling the split view state and does not do anything. If you have navigation item buttons, override this function and handle the panels manually.
- (void)splitViewDidReset;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,126 @@
//
// MVMCoreUISplitViewController+Extension.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 6/18/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public extension MVMCoreUISplitViewController {
/// Convenience function. Sets the navigation and split view properties for the view controller. Optional parameters use current value if not set.
static func setSplitViewController(for viewController: UIViewController, navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, leftPanelAccessible: Bool? = nil, rightPanelAccessible: Bool? = nil, progress: Float? = nil) {
guard let splitView = MVMCoreUISplitViewController.main(),
navigationController == splitView.navigationController,
navigationController.topViewController == viewController else {
NavigationController.set(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
return
}
splitView.set(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel, leftPanelAccessible: leftPanelAccessible, rightPanelAccessible: rightPanelAccessible, progress: progress)
}
/// Sets the navigation item for the view controller based on the model and splitview controller
func set(for viewController: UIViewController, navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, leftPanelAccessible: Bool? = nil, rightPanelAccessible: Bool? = nil, progress: Float? = nil) {
// Setup the panels.
setupPanels()
NavigationController.setNavigationUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
setLeftPanelIsAccessible(leftPanelAccessible ?? leftPanelIsAccessible, for: viewController, updateNavigationButtons: false)
setRightPanelIsAccessible(rightPanelAccessible ?? rightPanelIsAccessible, for: viewController, updateNavigationButtons: false)
setLeftNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
setRightNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
setNavigationIconColor(navigationItemModel.tintColor.uiColor)
if let progress = progress {
setBottomProgressBarProgress(progress)
}
}
/// Sets the left navigation items for the view controller based on model and splitview.
func setLeftNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) {
var leftItems: [UIBarButtonItem] = []
let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
// Add back button first.
if navigationItemModel?.alwaysShowBackButton != false {
if let backButtonModel = navigationItemModel?.backButton {
if navigationController.viewControllers.count > 1 || navigationItemModel!.alwaysShowBackButton ?? false {
leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
}
} else if let backButton = backButton,
navigationController.viewControllers.count > 1 {
leftItems.append(backButton)
}
}
// Add the panel button after the back button.
if let panelButton = leftPanelButton,
leftPanelIsAccessible,
!leftPanelStaysExtended() {
leftItems.append(panelButton)
}
// Add other model buttons
if let leftItemModels = navigationItemModel?.additionalLeftButtons {
for item in leftItemModels {
leftItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
}
}
// Add any buttons added by the splitview.
if let additionalLeftButtons = additionalLeftButtons(for: viewController) {
leftItems.append(contentsOf: additionalLeftButtons)
}
viewController.navigationItem.setLeftBarButtonItems(leftItems.count > 0 ? leftItems : nil, animated: !DisableAnimations.boolValue)
}
/// Sets the right navigation items for the view controller based on model and splitview.
func setRightNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) {
let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
var rightItems: [UIBarButtonItem] = []
// Add the panel button first.
if let panelButton = rightPanelButton,
rightPanelIsAccessible,
!rightPanelStaysExtended() {
rightItems.append(panelButton)
}
// Add other model buttons
if let rightItemModels = navigationItemModel?.additionalRightButtons {
for item in rightItemModels {
rightItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
}
}
// Add any buttons added by the splitview.
if let additionalRightButtons = additionalRightButtons(for: viewController) {
rightItems.append(contentsOf: additionalRightButtons)
}
viewController.navigationItem.setRightBarButtonItems(rightItems.count > 0 ? rightItems : nil, animated: !DisableAnimations.boolValue)
}
// MARK: - Legacy Functions
/// Convenience setter for legacy files. Sets the navigation item for the view controller based on the json and splitview controller
@objc static func setSplitViewController(for viewController: UIViewController, navigationController: UINavigationController, navigationJSON: [String: Any], leftPanelAccessible: Bool, rightPanelAccessible: Bool, progress: NSNumber?) throws {
guard let navigationItemModel = try MoleculeObjectMapping.shared()?.getMoleculeModelForJSON(navigationJSON) as? (MoleculeModelProtocol & NavigationItemModelProtocol) else {
throw ModelRegistry.Error.decoderOther(message: "Model not a bar model")
}
guard let splitView = MVMCoreUISplitViewController.main(),
navigationController == splitView.navigationController,
navigationController.topViewController == viewController else {
NavigationController.set(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
return
}
let progress = progress?.floatValue
splitView.set(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel, leftPanelAccessible: leftPanelAccessible, rightPanelAccessible: rightPanelAccessible, progress: progress)
}
}

View File

@ -67,10 +67,10 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
#pragma mark - Panel Functions
// Sets if the left panel accessible for the view controller. Will show or hide the button.
- (void)setLeftPanelIsAccessible:(BOOL)leftPanelIsAccessible forViewController:(nonnull UIViewController *)viewController;
- (void)setLeftPanelIsAccessible:(BOOL)leftPanelIsAccessible forViewController:(nonnull UIViewController *)viewController updateNavigationButtons:(BOOL)updateNavigationButtons;
// Sets if the right panel accessible for the view controller. Will show or hide the button.
- (void)setRightPanelIsAccessible:(BOOL)rightPanelIsAccessible forViewController:(nonnull UIViewController *)viewController;
- (void)setRightPanelIsAccessible:(BOOL)rightPanelIsAccessible forViewController:(nonnull UIViewController *)viewController updateNavigationButtons:(BOOL)updateNavigationButtons;
- (void)hideLeftPanelIfNeededAnimated:(BOOL)animated;
- (void)showLeftPanelAnimated:(BOOL)animated;
@ -94,6 +94,12 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
/// Updates the panels that are used.
- (void)setupPanels;
/// Returns if the left panel is staying extended (usually do to screen size threshold)
- (BOOL)leftPanelStaysExtended;
/// Returns if the right panel is staying extended (usually do to screen size threshold)
- (BOOL)rightPanelStaysExtended;
#pragma mark - Bottom Progress Bar
- (void)setBottomProgressBarProgress:(float)progress;

View File

@ -110,11 +110,11 @@ CGFloat const PanelAnimationDuration = 0.2;
}
- (nullable NSArray <UIBarButtonItem *>*)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController {
return viewController.navigationItem.leftBarButtonItems;
return nil;
}
- (nullable NSArray <UIBarButtonItem *>*)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController {
return viewController.navigationItem.rightBarButtonItems;
return nil;
}
- (CGFloat)leftPanelExtendedWidth {
@ -146,7 +146,7 @@ CGFloat const PanelAnimationDuration = 0.2;
}
- (nullable UIImage *)imageForBackButton {
return [MVMCoreUIUtility imageNamed:@"back"];
return [MVMCoreUIUtility imageNamed:@"nav_back"];
}
#pragma mark - Button Presses
@ -234,19 +234,27 @@ CGFloat const PanelAnimationDuration = 0.2;
}
}
- (BOOL)leftPanelStaysExtended {
MFNumberOfDrawers numberOfDrawers = [self numberOfDrawersShouldShow:self.transitionWidth];
return [self shouldExtendLeftPanel:numberOfDrawers] && (numberOfDrawers != MFOneDrawer || self.explictlyShowingPanel != self.rightPanel);
}
- (void)setLeftNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended {
NSMutableArray *leftBarButtonItems = [NSMutableArray array];
if ([viewController.navigationController.viewControllers count] > 1) {
[leftBarButtonItems addObject:self.backButton];
}
if ((accessible && !extended) && self.leftPanelButton) {
[leftBarButtonItems addObject:self.leftPanelButton];
}
NSArray *extraButtons = [self additionalLeftButtonsForViewController:viewController];
if (extraButtons) {
[leftBarButtonItems addObjectsFromArray:extraButtons];
}
if ((accessible && !extended) && self.leftPanelButton && ![extraButtons containsObject:self.leftPanelButton]) {
[leftBarButtonItems addObject:self.leftPanelButton];
}
[viewController.navigationItem setLeftBarButtonItems:(leftBarButtonItems.count > 0 ? leftBarButtonItems : nil) animated:!DisableAnimations];
}
- (void)setLeftPanelIsAccessible:(BOOL)leftPanelIsAccessible forViewController:(UIViewController *)viewController {
- (void)setLeftPanelIsAccessible:(BOOL)leftPanelIsAccessible forViewController:(UIViewController *)viewController updateNavigationButtons:(BOOL)updateNavigationButtons {
if ([self.leftPanel respondsToSelector:@selector(panelAvailable)]) {
self.leftPanelIsAccessible = leftPanelIsAccessible && [self.leftPanel panelAvailable];
} else {
@ -262,8 +270,7 @@ CGFloat const PanelAnimationDuration = 0.2;
} else {
// Determine if we should show the panel (extended based on width or from explicit action).
MFNumberOfDrawers numberOfDrawers = [self numberOfDrawersShouldShow:self.transitionWidth];
extended = [self shouldExtendLeftPanel:numberOfDrawers] && (numberOfDrawers != MFOneDrawer || self.explictlyShowingPanel != self.rightPanel);
extended = [self leftPanelStaysExtended];
if (extended || self.explictlyShowingPanel == self.leftPanel) {
[self showLeftPanelAnimated:NO explict:NO];
}
@ -272,7 +279,9 @@ CGFloat const PanelAnimationDuration = 0.2;
[self.leftPanel resetIconToDefault];
}
}
[self setLeftNavigationItemForViewController:viewController accessible:self.leftPanelIsAccessible extended:extended];
if (updateNavigationButtons) {
[self setLeftNavigationItemForViewController:viewController accessible:self.leftPanelIsAccessible extended:extended];
}
}];
}
@ -407,10 +416,10 @@ CGFloat const PanelAnimationDuration = 0.2;
- (void)setRightNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended {
NSMutableArray *navigationItems = [[NSMutableArray alloc] init];
NSArray *extraButtons = [self additionalRightButtonsForViewController:viewController];
if ((accessible && !extended) && self.rightPanelButton && ![extraButtons containsObject:self.rightPanelButton]) {
if ((accessible && !extended) && self.rightPanelButton) {
[navigationItems addObject:self.rightPanelButton];
}
NSArray *extraButtons = [self additionalRightButtonsForViewController:viewController];
if (extraButtons) {
[navigationItems addObjectsFromArray:extraButtons];
}
@ -440,7 +449,12 @@ CGFloat const PanelAnimationDuration = 0.2;
}
}
- (void)setRightPanelIsAccessible:(BOOL)rightPanelIsAccessible forViewController:(UIViewController *)viewController {
- (BOOL)rightPanelStaysExtended {
MFNumberOfDrawers numberOfDrawers = [self numberOfDrawersShouldShow:self.transitionWidth];
return [self shouldExtendRightPanel:numberOfDrawers] && (numberOfDrawers != MFOneDrawer || self.explictlyShowingPanel != self.leftPanel);
}
- (void)setRightPanelIsAccessible:(BOOL)rightPanelIsAccessible forViewController:(UIViewController *)viewController updateNavigationButtons:(BOOL)updateNavigationButtons {
if ([self.rightPanel respondsToSelector:@selector(panelAvailable)]) {
self.rightPanelIsAccessible = rightPanelIsAccessible && [self.rightPanel panelAvailable];
@ -458,8 +472,7 @@ CGFloat const PanelAnimationDuration = 0.2;
} else {
// Determine if we should show the right panel (extended based on width or from explicit action).
MFNumberOfDrawers numberOfDrawers = [self numberOfDrawersShouldShow:self.transitionWidth];
extended = [self shouldExtendRightPanel:numberOfDrawers] && (numberOfDrawers != MFOneDrawer || self.explictlyShowingPanel != self.leftPanel);
extended = [self rightPanelStaysExtended];
if (extended || self.explictlyShowingPanel == self.rightPanel) {
[self showRightPanelAnimated:NO explict:NO];
}
@ -468,7 +481,10 @@ CGFloat const PanelAnimationDuration = 0.2;
[self.rightPanel resetIconToDefault];
}
}
[self setRightNavigationItemForViewController:viewController accessible:rightPanelIsAccessible extended:extended];
if (updateNavigationButtons) {
[self setRightNavigationItemForViewController:viewController accessible:rightPanelIsAccessible extended:extended];
}
}];
}
@ -918,7 +934,7 @@ CGFloat const PanelAnimationDuration = 0.2;
self.extendedDrawers = MFExtendedDrawerLeft | MFExtendedDrawerRight;
self.prioritizedExtendedPanel = MFExtendedDrawerLeft;
self.view.backgroundColor = [UIColor blackColor];
self.view.backgroundColor = [UIColor whiteColor];
}
- (void)viewDidLayoutSubviews {
@ -974,11 +990,15 @@ CGFloat const PanelAnimationDuration = 0.2;
}
- (void)resetDrawers {
[self setLeftPanelIsAccessible:self.leftPanelIsAccessible forViewController:self.navigationItemViewController];
[self setRightPanelIsAccessible:self.rightPanelIsAccessible forViewController:self.navigationItemViewController];
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
if ([self.navigationItemViewController respondsToSelector:@selector(splitViewDidReset)]) {
[((UIViewController<MVMCoreUIDetailViewProtocol> *)self.navigationItemViewController) splitViewDidReset];
} else {
[self setLeftPanelIsAccessible:self.leftPanelIsAccessible forViewController:self.navigationItemViewController updateNavigationButtons:YES];
[self setRightPanelIsAccessible:self.rightPanelIsAccessible forViewController:self.navigationItemViewController updateNavigationButtons:YES];
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}
}
- (UIStatusBarStyle)preferredStatusBarStyle {
@ -1069,6 +1089,7 @@ CGFloat const PanelAnimationDuration = 0.2;
if ([self.rightPanelButton respondsToSelector:@selector(setIconColor:)]) {
[((UIBarButtonItem <MVMCoreUIPanelButtonProtocol>*)self.rightPanelButton) setIconColor:color];
}
[self.backButton setTintColor:color];
}
@end

View File

@ -13,7 +13,7 @@ public extension Dictionary {
throw ModelRegistry.Error.decoderOther(message: "Dictionary is not of type [String: Any]")
}
guard let actionType = ModelRegistry.getType(for: castedSelf.stringForkey(KeyActionType), with: ActionModelProtocol.self) else {
throw ModelRegistry.Error.decoderErrorModelNotMapped
throw ModelRegistry.Error.decoderErrorModelNotMapped()
}
guard let actionModel = try actionType.decode(jsonDict: castedSelf) as? ActionModelProtocol else {
throw ModelRegistry.Error.decoderOther(message: "Could not decode to ActionModelProtocol")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 535 B

View File

@ -2,17 +2,17 @@
"images" : [
{
"idiom" : "universal",
"filename" : "back.png",
"filename" : "nav_back.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "back@2x.png",
"filename" : "nav_back@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "back@3x.png",
"filename" : "nav_back@3x.png",
"scale" : "3x"
}
],

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

View File

@ -2,17 +2,17 @@
"images" : [
{
"idiom" : "universal",
"filename" : "closeXBlack.png",
"filename" : "nav_close.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "closeXBlack@2x.png",
"filename" : "nav_close@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "closeXBlack@3x.png",
"filename" : "nav_close@3x.png",
"scale" : "3x"
}
],

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 B

View File

@ -9,7 +9,7 @@
// MARK: Accessibility
"AccCloseButton" = "Close";
"swipe_to_select_with_action_hint" = "swipe up or down to select action, then double tap to select.";
"AccDisabled" = "Disabled";
// MARK: Tab
"AccTab" = ", tab";

View File

@ -8,6 +8,7 @@
// Accessibility
"swipe_to_select_with_action_hint" = "deslízate hacia arriba o hacia abajo para seleccionar la acción, luego toca dos veces para seleccionar.";
"AccDisabled" = "desactivado";
"AccCloseButton" = "Cerrar";
// Tab

View File

@ -8,6 +8,7 @@
// Accessibility
"swipe_to_select_with_action_hint" = "deslízate hacia arriba o hacia abajo para seleccionar la acción, luego toca dos veces para seleccionar.";
"AccDisabled" = "desactivado";
"AccCloseButton" = "Cerrar";
// Tab

View File

@ -13,7 +13,7 @@ public extension MVMCoreUICommonViewsUtility {
/// Add the close button (x) to the top right of the view. TODO: update this logic.
@objc static func addCloseButton(to view: UIView, action: @escaping ButtonAction, centeredVertically: Bool = false) -> Button {
let button = Button()
if let image = MVMCoreUIUtility.imageNamed("closeXBlack")?.withRenderingMode(.alwaysTemplate) {
if let image = MVMCoreUIUtility.imageNamed("nav_close")?.withRenderingMode(.alwaysTemplate) {
button.setImage(image, for: .normal)
}
button.tintColor = .black