Merge branch 'develop' into feature/headers_H1_button

# Conflicts:
#	MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift
This commit is contained in:
Lekshmi S 2020-03-18 09:23:34 +05:30
commit 9187e0adf3
128 changed files with 2429 additions and 1054 deletions

View File

@ -10,12 +10,25 @@
01004F3022721C3800991ECC /* RadioButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01004F2F22721C3800991ECC /* RadioButton.swift */; };
0103B84E23D7E33A009C315C /* HeadlineBodyToggleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0103B84D23D7E33A009C315C /* HeadlineBodyToggleModel.swift */; };
0105618D224BBE7700E1557D /* FormValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618A224BBE7700E1557D /* FormValidator.swift */; };
0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */; };
0105618F224BBE7700E1557D /* FormValidator+FormParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */; };
0116A4E5228B19640094F3ED /* RadioButtonSelectionHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */; };
011B58F023A2AA980085F53C /* ListItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */; };
011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011B58F123A2AE2C0085F53C /* DropDownListItemModel.swift */; };
011D958524042432000E3791 /* RulesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D958424042432000E3791 /* RulesProtocol.swift */; };
011D958724042492000E3791 /* FormFieldProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D958624042492000E3791 /* FormFieldProtocol.swift */; };
011D95892404249B000E3791 /* FormProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95882404249B000E3791 /* FormProtocol.swift */; };
011D959B240451E3000E3791 /* RuleRequiredModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D959A240451E3000E3791 /* RuleRequiredModel.swift */; };
011D959D2404536F000E3791 /* RuleAnyValueChangedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D959C2404536F000E3791 /* RuleAnyValueChangedModel.swift */; };
011D959F240453A1000E3791 /* RuleAllValueChangedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D959E240453A1000E3791 /* RuleAllValueChangedModel.swift */; };
011D95A1240453D0000E3791 /* RuleEqualsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95A0240453D0000E3791 /* RuleEqualsModel.swift */; };
011D95A3240453F8000E3791 /* RuleRegexModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95A2240453F8000E3791 /* RuleRegexModel.swift */; };
011D95A5240455DC000E3791 /* FormGroupRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95A4240455DC000E3791 /* FormGroupRule.swift */; };
011D95A924057AC7000E3791 /* FormActionFieldProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95A824057AC7000E3791 /* FormActionFieldProtocol.swift */; };
011D95AB2405C553000E3791 /* FormItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95AA2405C553000E3791 /* FormItemProtocol.swift */; };
011D95AD2406BB57000E3791 /* FormHolderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95AC2406BB57000E3791 /* FormHolderProtocol.swift */; };
011D95AF2407266E000E3791 /* RadioButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95AE2407266E000E3791 /* RadioButtonModel.swift */; };
011D9602240DA20A000E3791 /* ValidProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D9601240DA20A000E3791 /* ValidProtocol.swift */; };
011D9626240EBB16000E3791 /* RadioButtonLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D9625240EBB16000E3791 /* RadioButtonLabelModel.swift */; };
011D9628240EFA1E000E3791 /* MFViewController+Form.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D9627240EFA1E000E3791 /* MFViewController+Form.swift */; };
012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A889B23889E8400FE3DA1 /* TemplateModelProtocol.swift */; };
012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88AC238C418100FE3DA1 /* TemplateProtocol.swift */; };
012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88B0238C880100FE3DA1 /* CarouselPagingModelProtocol.swift */; };
@ -26,7 +39,6 @@
012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88AE238C626E00FE3DA1 /* CarouselModel.swift */; };
012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88EB238F084D00FE3DA1 /* FooterModel.swift */; };
012A88F123985E0100FE3DA1 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88F023985E0100FE3DA1 /* Color.swift */; };
012CA99A2384A687003F810F /* MFTextField+ModelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012CA9992384A687003F810F /* MFTextField+ModelExtension.swift */; };
012CA99E2385A2D3003F810F /* MFView+ModelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012CA99D2385A2D3003F810F /* MFView+ModelExtension.swift */; };
013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */; };
014AA72423C501E2006F3E93 /* MoleculeContainerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */; };
@ -43,13 +55,11 @@
017BEB382360C6AC0024EF95 /* RadioButtonLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */; };
017BEB3C2361EA1D0024EF95 /* MFViewController+Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB3B2361EA1D0024EF95 /* MFViewController+Model.swift */; };
017BEB4023620A230024EF95 /* TextFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB3F23620A230024EF95 /* TextFieldModel.swift */; };
017BEB4223620AD20024EF95 /* FormModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB4123620AD20024EF95 /* FormModelProtocol.swift */; };
017BEB442362192F0024EF95 /* MVMCoreUIMoleculeMappingObject+ModelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB432362192F0024EF95 /* MVMCoreUIMoleculeMappingObject+ModelExtension.swift */; };
017BEB48236230DB0024EF95 /* MoleculeViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */; };
017BEB4A236235BA0024EF95 /* ModelMoleculeViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB49236235BA0024EF95 /* ModelMoleculeViewProtocol.swift */; };
017BEB7B236763000024EF95 /* LineModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB7A236763000024EF95 /* LineModel.swift */; };
017BEB7F23676E870024EF95 /* MoleculeObjectMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB7E23676E870024EF95 /* MoleculeObjectMapping.swift */; };
0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0198F79E225679870066C936 /* FormValidationProtocol.swift */; };
0198F7A62256A80B0066C936 /* MFRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 0198F7A02256A80A0066C936 /* MFRadioButton.h */; settings = {ATTRIBUTES = (Public, ); }; };
0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0198F7A22256A80A0066C936 /* MFRadioButton.m */; };
01C851D323CF9E740021F976 /* LabelToggleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01C851D223CF9E740021F976 /* LabelToggleModel.swift */; };
@ -81,6 +91,7 @@
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; };
0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */; };
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */; };
0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */; };
0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; };
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; };
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; };
@ -106,13 +117,27 @@
52267A0723FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52267A0623FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift */; };
5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5248BFEA23F12E350059236A /* ListThreeColumnPlanDataDivider.swift */; };
5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */; };
525019DD2406430800EED91C /* ListProgressBarDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525019DB2406430700EED91C /* ListProgressBarDataModel.swift */; };
525019DE2406430800EED91C /* ListProgressBarData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525019DC2406430800EED91C /* ListProgressBarData.swift */; };
525019E52406852100EED91C /* ListFourColumnDataUsageDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525019E42406852100EED91C /* ListFourColumnDataUsageDividerModel.swift */; };
525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525019E62406853600EED91C /* ListFourColumnDataUsageDivider.swift */; };
525239C02407BCFF00454969 /* ListTwoColumnPriceDetailsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525239BF2407BCFF00454969 /* ListTwoColumnPriceDetailsModel.swift */; };
525239C22407BD1000454969 /* ListTwoColumnPriceDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525239C12407BD1000454969 /* ListTwoColumnPriceDetails.swift */; };
526A265C240D1FF700B0D828 /* ListTwoColumnCompareChangesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 526A265B240D1FF700B0D828 /* ListTwoColumnCompareChangesModel.swift */; };
526A265E240D200500B0D828 /* ListTwoColumnCompareChanges.swift in Sources */ = {isa = PBXBuildFile; fileRef = 526A265D240D200500B0D828 /* ListTwoColumnCompareChanges.swift */; };
52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */; };
52B201D324081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */; };
8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */; };
8D070BB2241B56AD0099AC56 /* ListRightVariableTotalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */; };
8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */; };
8D084AD22410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D084AD12410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift */; };
8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */; };
8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */; };
8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */; };
942C372E241149170066E45E /* NHaasGroteskDSStd-75Bd.otf in Resources */ = {isa = PBXBuildFile; fileRef = 942C372C241149170066E45E /* NHaasGroteskDSStd-75Bd.otf */; };
942C372F241149170066E45E /* NHaasGroteskDSStd-55Rg.otf in Resources */ = {isa = PBXBuildFile; fileRef = 942C372D241149170066E45E /* NHaasGroteskDSStd-55Rg.otf */; };
942C378C2412F4FA0066E45E /* ModalMoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */; };
942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 942C378D2412F5B60066E45E /* ModalMoleculeStackTemplate.swift */; };
9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; };
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; };
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; };
@ -124,7 +149,6 @@
9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; };
9458C3172406C8FD00930963 /* UIFont+FontWrapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 9458C3152406C8FD00930963 /* UIFont+FontWrapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
9458C3182406C8FD00930963 /* UIFont+FontWrapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 9458C3162406C8FD00930963 /* UIFont+FontWrapping.m */; };
946EE1BA237B66D80036751F /* MoleculeModelHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1B9237B66D80036751F /* MoleculeModelHelper.swift */; };
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; };
94AF4A3E23E9D13900676048 /* MFCaretButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 94AF4A3C23E9D13900676048 /* MFCaretButton.h */; settings = {ATTRIBUTES = (Public, ); }; };
94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 94AF4A3D23E9D13900676048 /* MFCaretButton.m */; };
@ -151,6 +175,10 @@
AA119DEA240FB430005F98FD /* HeadersH1ButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA119DE9240FB430005F98FD /* HeadersH1ButtonModel.swift */; };
AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA11A41E23F15D3100D7962F /* ListRightVariablePayments.swift */; };
AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */; };
BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */; };
BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */; };
AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */; };
AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */; };
C003506123AA94CD00B6AC29 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = C003506023AA94CD00B6AC29 /* Button.swift */; };
C07065C42395677300FBF997 /* Link.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07065C32395677300FBF997 /* Link.swift */; };
C695A67F23C9830600BFB94E /* UnOrderedListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */; };
@ -180,7 +208,11 @@
D22D1F47220496A30077CEC0 /* MVMCoreUISwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */; };
D22D1F562204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = D22D1F542204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
D22D1F572204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D22D1F552204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m */; };
D22D8395241FB41200D3DF69 /* UIStackView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */; };
D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */; };
D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; };
D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; };
D256E9932412880000360572 /* Header.swift in Sources */ = {isa = PBXBuildFile; fileRef = D256E9922412880000360572 /* Header.swift */; };
D260105323CEA61600764D80 /* ToggleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260105223CEA61600764D80 /* ToggleModel.swift */; };
D260105523CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260105423CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift */; };
D260105923D0A92900764D80 /* ContainerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260105823D0A92900764D80 /* ContainerProtocol.swift */; };
@ -367,12 +399,25 @@
01004F2F22721C3800991ECC /* RadioButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButton.swift; sourceTree = "<group>"; };
0103B84D23D7E33A009C315C /* HeadlineBodyToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyToggleModel.swift; sourceTree = "<group>"; };
0105618A224BBE7700E1557D /* FormValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidator.swift; sourceTree = "<group>"; };
0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+TextFields.swift"; sourceTree = "<group>"; };
0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+FormParams.swift"; sourceTree = "<group>"; };
0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonSelectionHelper.swift; sourceTree = "<group>"; };
011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemModelProtocol.swift; sourceTree = "<group>"; };
011B58F123A2AE2C0085F53C /* DropDownListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropDownListItemModel.swift; sourceTree = "<group>"; };
011D958424042432000E3791 /* RulesProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RulesProtocol.swift; sourceTree = "<group>"; };
011D958624042492000E3791 /* FormFieldProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormFieldProtocol.swift; sourceTree = "<group>"; };
011D95882404249B000E3791 /* FormProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormProtocol.swift; sourceTree = "<group>"; };
011D959A240451E3000E3791 /* RuleRequiredModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleRequiredModel.swift; sourceTree = "<group>"; };
011D959C2404536F000E3791 /* RuleAnyValueChangedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyValueChangedModel.swift; sourceTree = "<group>"; };
011D959E240453A1000E3791 /* RuleAllValueChangedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAllValueChangedModel.swift; sourceTree = "<group>"; };
011D95A0240453D0000E3791 /* RuleEqualsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleEqualsModel.swift; sourceTree = "<group>"; };
011D95A2240453F8000E3791 /* RuleRegexModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleRegexModel.swift; sourceTree = "<group>"; };
011D95A4240455DC000E3791 /* FormGroupRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormGroupRule.swift; sourceTree = "<group>"; };
011D95A824057AC7000E3791 /* FormActionFieldProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormActionFieldProtocol.swift; sourceTree = "<group>"; };
011D95AA2405C553000E3791 /* FormItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormItemProtocol.swift; sourceTree = "<group>"; };
011D95AC2406BB57000E3791 /* FormHolderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormHolderProtocol.swift; sourceTree = "<group>"; };
011D95AE2407266E000E3791 /* RadioButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonModel.swift; sourceTree = "<group>"; };
011D9601240DA20A000E3791 /* ValidProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidProtocol.swift; sourceTree = "<group>"; };
011D9625240EBB16000E3791 /* RadioButtonLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioButtonLabelModel.swift; sourceTree = "<group>"; };
011D9627240EFA1E000E3791 /* MFViewController+Form.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFViewController+Form.swift"; sourceTree = "<group>"; };
012A889B23889E8400FE3DA1 /* TemplateModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateModelProtocol.swift; sourceTree = "<group>"; };
012A88AC238C418100FE3DA1 /* TemplateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateProtocol.swift; sourceTree = "<group>"; };
012A88AE238C626E00FE3DA1 /* CarouselModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselModel.swift; sourceTree = "<group>"; };
@ -383,7 +428,6 @@
012A88C7238DB02000FE3DA1 /* ModelMoleculeDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelMoleculeDelegateProtocol.swift; sourceTree = "<group>"; };
012A88EB238F084D00FE3DA1 /* FooterModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FooterModel.swift; sourceTree = "<group>"; };
012A88F023985E0100FE3DA1 /* Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = "<group>"; };
012CA9992384A687003F810F /* MFTextField+ModelExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFTextField+ModelExtension.swift"; sourceTree = "<group>"; };
012CA99D2385A2D3003F810F /* MFView+ModelExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFView+ModelExtension.swift"; sourceTree = "<group>"; };
013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIContentMode+Extension.swift"; sourceTree = "<group>"; };
014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeContainerModel.swift; sourceTree = "<group>"; };
@ -400,13 +444,11 @@
017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioButtonLabel.swift; sourceTree = "<group>"; };
017BEB3B2361EA1D0024EF95 /* MFViewController+Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFViewController+Model.swift"; sourceTree = "<group>"; };
017BEB3F23620A230024EF95 /* TextFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldModel.swift; sourceTree = "<group>"; };
017BEB4123620AD20024EF95 /* FormModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormModelProtocol.swift; sourceTree = "<group>"; };
017BEB432362192F0024EF95 /* MVMCoreUIMoleculeMappingObject+ModelExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUIMoleculeMappingObject+ModelExtension.swift"; sourceTree = "<group>"; };
017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeViewProtocol.swift; sourceTree = "<group>"; };
017BEB49236235BA0024EF95 /* ModelMoleculeViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelMoleculeViewProtocol.swift; sourceTree = "<group>"; };
017BEB7A236763000024EF95 /* LineModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineModel.swift; sourceTree = "<group>"; };
017BEB7E23676E870024EF95 /* MoleculeObjectMapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeObjectMapping.swift; sourceTree = "<group>"; };
0198F79E225679870066C936 /* FormValidationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidationProtocol.swift; sourceTree = "<group>"; };
0198F7A02256A80A0066C936 /* MFRadioButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFRadioButton.h; sourceTree = "<group>"; };
0198F7A22256A80A0066C936 /* MFRadioButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFRadioButton.m; sourceTree = "<group>"; };
01C851D223CF9E740021F976 /* LabelToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelToggleModel.swift; sourceTree = "<group>"; };
@ -426,6 +468,7 @@
0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CATransaction+Extension.swift"; sourceTree = "<group>"; };
0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = "<group>"; };
0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleGuidelinesProtocol.swift; sourceTree = "<group>"; };
0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyRequiredModel.swift; sourceTree = "<group>"; };
0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseDropdownEntryField.swift; sourceTree = "<group>"; };
0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = "<group>"; };
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = "<group>"; };
@ -454,14 +497,28 @@
52267A0623FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextAllTextAndLinks.swift; sourceTree = "<group>"; };
5248BFEA23F12E350059236A /* ListThreeColumnPlanDataDivider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnPlanDataDivider.swift; sourceTree = "<group>"; };
5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnPlanDataDividerModel.swift; sourceTree = "<group>"; };
525019DB2406430700EED91C /* ListProgressBarDataModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListProgressBarDataModel.swift; sourceTree = "<group>"; };
525019DC2406430800EED91C /* ListProgressBarData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListProgressBarData.swift; sourceTree = "<group>"; };
525019E42406852100EED91C /* ListFourColumnDataUsageDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageDividerModel.swift; sourceTree = "<group>"; };
525019E62406853600EED91C /* ListFourColumnDataUsageDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageDivider.swift; sourceTree = "<group>"; };
525239BF2407BCFF00454969 /* ListTwoColumnPriceDetailsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDetailsModel.swift; sourceTree = "<group>"; };
525239C12407BD1000454969 /* ListTwoColumnPriceDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDetails.swift; sourceTree = "<group>"; };
526A265B240D1FF700B0D828 /* ListTwoColumnCompareChangesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnCompareChangesModel.swift; sourceTree = "<group>"; };
526A265D240D200500B0D828 /* ListTwoColumnCompareChanges.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnCompareChanges.swift; sourceTree = "<group>"; };
52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAndPaymentMethod.swift; sourceTree = "<group>"; };
52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAndPaymentMethodModel.swift; sourceTree = "<group>"; };
8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableTotalDataModel.swift; sourceTree = "<group>"; };
8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableTotalData.swift; sourceTree = "<group>"; };
8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextBodyTextModel.swift; sourceTree = "<group>"; };
8D084AD12410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextBodyText.swift; sourceTree = "<group>"; };
8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaret.swift; sourceTree = "<group>"; };
8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretModel.swift; sourceTree = "<group>"; };
8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextAllTextAndLinksModel.swift; sourceTree = "<group>"; };
9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = "<group>"; };
942C372C241149170066E45E /* NHaasGroteskDSStd-75Bd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NHaasGroteskDSStd-75Bd.otf"; sourceTree = "<group>"; };
942C372D241149170066E45E /* NHaasGroteskDSStd-55Rg.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NHaasGroteskDSStd-55Rg.otf"; sourceTree = "<group>"; };
942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalMoleculeListTemplate.swift; sourceTree = "<group>"; };
942C378D2412F5B60066E45E /* ModalMoleculeStackTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalMoleculeStackTemplate.swift; sourceTree = "<group>"; };
9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = "<group>"; };
943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = "<group>"; };
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = "<group>"; };
@ -473,7 +530,6 @@
9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = "<group>"; };
9458C3152406C8FD00930963 /* UIFont+FontWrapping.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIFont+FontWrapping.h"; sourceTree = "<group>"; };
9458C3162406C8FD00930963 /* UIFont+FontWrapping.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIFont+FontWrapping.m"; sourceTree = "<group>"; };
946EE1B9237B66D80036751F /* MoleculeModelHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeModelHelper.swift; sourceTree = "<group>"; };
948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = "<group>"; };
94AF4A3C23E9D13900676048 /* MFCaretButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MFCaretButton.h; sourceTree = "<group>"; };
94AF4A3D23E9D13900676048 /* MFCaretButton.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MFCaretButton.m; sourceTree = "<group>"; };
@ -498,6 +554,10 @@
AA119DE9240FB430005F98FD /* HeadersH1ButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH1ButtonModel.swift; sourceTree = "<group>"; };
AA11A41E23F15D3100D7962F /* ListRightVariablePayments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePayments.swift; sourceTree = "<group>"; };
AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePaymentsModel.swift; sourceTree = "<group>"; };
BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsectionModel.swift; sourceTree = "<group>"; };
BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsection.swift; sourceTree = "<group>"; };
AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyText.swift; sourceTree = "<group>"; };
AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyTextModel.swift; sourceTree = "<group>"; };
C003506023AA94CD00B6AC29 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = "<group>"; };
C07065C32395677300FBF997 /* Link.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Link.swift; sourceTree = "<group>"; };
C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnOrderedListModel.swift; sourceTree = "<group>"; };
@ -527,7 +587,11 @@
D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUISwitch.m; sourceTree = "<group>"; };
D22D1F542204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIStackableViewController.h; sourceTree = "<group>"; };
D22D1F552204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIStackableViewController.m; sourceTree = "<group>"; };
D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+Extension.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>"; };
D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = "<group>"; };
D256E9922412880000360572 /* Header.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Header.swift; sourceTree = "<group>"; };
D260105223CEA61600764D80 /* ToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleModel.swift; sourceTree = "<group>"; };
D260105423CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUISwitch+Model.swift"; sourceTree = "<group>"; };
D260105823D0A92900764D80 /* ContainerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerProtocol.swift; sourceTree = "<group>"; };
@ -740,7 +804,6 @@
isa = PBXGroup;
children = (
014AA72323C501E2006F3E93 /* ContainerModelProtocol.swift */,
017BEB4123620AD20024EF95 /* FormModelProtocol.swift */,
012A88C3238D86E600FE3DA1 /* CarouselItemModelProtocol.swift */,
012A88B0238C880100FE3DA1 /* CarouselPagingModelProtocol.swift */,
01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */,
@ -752,6 +815,22 @@
path = ModelProtocols;
sourceTree = "<group>";
};
011D958A24042794000E3791 /* Rules */ = {
isa = PBXGroup;
children = (
011D958424042432000E3791 /* RulesProtocol.swift */,
011D959A240451E3000E3791 /* RuleRequiredModel.swift */,
011D959C2404536F000E3791 /* RuleAnyValueChangedModel.swift */,
011D959E240453A1000E3791 /* RuleAllValueChangedModel.swift */,
011D95A0240453D0000E3791 /* RuleEqualsModel.swift */,
011D95A2240453F8000E3791 /* RuleRegexModel.swift */,
011D95A4240455DC000E3791 /* FormGroupRule.swift */,
0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */,
);
name = Rules;
path = Rules/Rules;
sourceTree = "<group>";
};
012A88EF23985E0100FE3DA1 /* CustomPrimitives */ = {
isa = PBXGroup;
children = (
@ -764,7 +843,6 @@
isa = PBXGroup;
children = (
011B58EE23A2AA850085F53C /* ModelProtocols */,
946EE1B5237B663A0036751F /* Extensions */,
);
path = Models;
sourceTree = "<group>";
@ -772,10 +850,14 @@
01C74D87224298E2009C25A3 /* FormUIHelpers */ = {
isa = PBXGroup;
children = (
0198F79E225679870066C936 /* FormValidationProtocol.swift */,
011D95882404249B000E3791 /* FormProtocol.swift */,
011D95AC2406BB57000E3791 /* FormHolderProtocol.swift */,
011D95AA2405C553000E3791 /* FormItemProtocol.swift */,
011D958624042492000E3791 /* FormFieldProtocol.swift */,
011D95A824057AC7000E3791 /* FormActionFieldProtocol.swift */,
011D9601240DA20A000E3791 /* ValidProtocol.swift */,
0105618A224BBE7700E1557D /* FormValidator.swift */,
0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */,
0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */,
011D958A24042794000E3791 /* Rules */,
);
path = FormUIHelpers;
sourceTree = "<group>";
@ -811,11 +893,22 @@
path = Link;
sourceTree = "<group>";
};
5206F150241144A900658DC5 /* Headers */ = {
isa = PBXGroup;
children = (
AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */,
AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */,
);
path = Headers;
sourceTree = "<group>";
};
52267A0523FFE0A900906CBA /* OneColumn */ = {
isa = PBXGroup;
children = (
8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */,
52267A0623FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift */,
8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */,
8D084AD12410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift */,
);
path = OneColumn;
sourceTree = "<group>";
@ -829,12 +922,29 @@
path = FourColumn;
sourceTree = "<group>";
};
946EE1B5237B663A0036751F /* Extensions */ = {
525239C32407FFCC00454969 /* LockUps */ = {
isa = PBXGroup;
children = (
946EE1B9237B66D80036751F /* MoleculeModelHelper.swift */,
525019DB2406430700EED91C /* ListProgressBarDataModel.swift */,
525019DC2406430800EED91C /* ListProgressBarData.swift */,
);
path = Extensions;
path = LockUps;
sourceTree = "<group>";
};
525665CB24211FD5007BF25F /* OneColumn */ = {
isa = PBXGroup;
children = (
BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */,
BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */,
);
path = OneColumn;
sourceTree = "<group>";
};
526A265A240D1FCE00B0D828 /* TwoColumn */ = {
isa = PBXGroup;
children = (
);
path = TwoColumn;
sourceTree = "<group>";
};
94C2D9822386F3E30006CF46 /* Label */ = {
@ -865,6 +975,8 @@
children = (
AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */,
AA11A41E23F15D3100D7962F /* ListRightVariablePayments.swift */,
8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */,
8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */,
C7F8012223E846C300396FBD /* ListRVWheelModel.swift */,
C7F8012023E8303200396FBD /* ListRVWheel.swift */,
);
@ -1043,6 +1155,8 @@
D22B38E923F4E07800490EF6 /* DesignedComponents */ = {
isa = PBXGroup;
children = (
5206F150241144A900658DC5 /* Headers */,
525239C32407FFCC00454969 /* LockUps */,
D22B38EC23F4E10700490EF6 /* SectionDividers */,
D22B38EA23F4E08B00490EF6 /* List */,
AA119DE7240FB41C005F98FD /* HeadersH1Button.swift */,
@ -1054,6 +1168,7 @@
D22B38EA23F4E08B00490EF6 /* List */ = {
isa = PBXGroup;
children = (
D22D8396241FDE4700D3DF69 /* TwoColumn */,
52267A0523FFE0A900906CBA /* OneColumn */,
AA4FC2A323F4F69600E251DB /* RightVariable */,
D22B38EB23F4E0AE00490EF6 /* LeftVariable */,
@ -1077,6 +1192,8 @@
D22B38EC23F4E10700490EF6 /* SectionDividers */ = {
isa = PBXGroup;
children = (
525665CB24211FD5007BF25F /* OneColumn */,
526A265A240D1FCE00B0D828 /* TwoColumn */,
525019E3240684E500EED91C /* FourColumn */,
D22B38ED23F4E11100490EF6 /* ThreeColumn */,
);
@ -1101,6 +1218,19 @@
path = Legacy;
sourceTree = "<group>";
};
D22D8396241FDE4700D3DF69 /* TwoColumn */ = {
isa = PBXGroup;
children = (
D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */,
D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */,
526A265B240D1FF700B0D828 /* ListTwoColumnCompareChangesModel.swift */,
526A265D240D200500B0D828 /* ListTwoColumnCompareChanges.swift */,
525239BF2407BCFF00454969 /* ListTwoColumnPriceDetailsModel.swift */,
525239C12407BD1000454969 /* ListTwoColumnPriceDetails.swift */,
);
path = TwoColumn;
sourceTree = "<group>";
};
D260105723CF9CC500764D80 /* Doughnut */ = {
isa = PBXGroup;
children = (
@ -1161,11 +1291,13 @@
012A88AC238C418100FE3DA1 /* TemplateProtocol.swift */,
014AA72823C5059B006F3E93 /* StackPageTemplateModel.swift */,
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */,
942C378D2412F5B60066E45E /* ModalMoleculeStackTemplate.swift */,
014AA72923C5059B006F3E93 /* StackCenteredPageTemplateModel.swift */,
D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */,
D28A837A23C928DA00DFE4FC /* MoleculeListCellProtocol.swift */,
014AA72C23C5059B006F3E93 /* ListPageTemplateModel.swift */,
D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */,
942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */,
014AA72A23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift */,
D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */,
);
@ -1200,6 +1332,7 @@
D224798E2316A995003FCCF9 /* HorizontalCombinationViews */,
D224798D2316A988003FCCF9 /* VerticalCombinationViews */,
01EB368C23609801006832FA /* HeaderModel.swift */,
D256E9922412880000360572 /* Header.swift */,
D2D90B41240463E100DD6EC9 /* MoleculeHeaderModel.swift */,
D2A514662213885800345BFB /* MoleculeHeaderView.swift */,
012A88EB238F084D00FE3DA1 /* FooterModel.swift */,
@ -1209,6 +1342,7 @@
D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */,
D28A838423CCCA8900DFE4FC /* ScrollerModel.swift */,
D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */,
011D9625240EBB16000E3791 /* RadioButtonLabelModel.swift */,
017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */,
017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */,
017BEB49236235BA0024EF95 /* ModelMoleculeViewProtocol.swift */,
@ -1223,6 +1357,7 @@
D29DF16021E69996003B2FB9 /* MFViewController.h */,
D29DF15F21E69996003B2FB9 /* MFViewController.m */,
017BEB3B2361EA1D0024EF95 /* MFViewController+Model.swift */,
011D9627240EFA1E000E3791 /* MFViewController+Form.swift */,
D29DF28F21E7ADB8003B2FB9 /* MFScrollingViewController.h */,
D29DF29021E7ADB8003B2FB9 /* MFScrollingViewController.m */,
D29DF29121E7ADB8003B2FB9 /* ProgrammaticScrollViewController.h */,
@ -1250,6 +1385,7 @@
D29DF11421E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m */,
D22479932316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift */,
0AA33B33239813C50067DD0F /* UIColor+Extension.swift */,
D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */,
);
path = Categories;
sourceTree = "<group>";
@ -1395,7 +1531,6 @@
0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */,
0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */,
017BEB3F23620A230024EF95 /* TextFieldModel.swift */,
012CA9992384A687003F810F /* MFTextField+ModelExtension.swift */,
);
path = TextFields;
sourceTree = "<group>";
@ -1485,6 +1620,8 @@
94CA227924058533002D6750 /* VerizonNHGeDS-Regular.otf */,
94CA227824058533002D6750 /* VerizonNHGeTX-Bold.otf */,
94CA227B24058533002D6750 /* VerizonNHGeTX-Regular.otf */,
942C372D241149170066E45E /* NHaasGroteskDSStd-55Rg.otf */,
942C372C241149170066E45E /* NHaasGroteskDSStd-75Bd.otf */,
D29DF31721ECECC0003B2FB9 /* OCRAExtended.ttf */,
);
path = Fonts;
@ -1694,6 +1831,8 @@
0A21DB86235E06EF00C160A2 /* MFTextField.xib in Resources */,
94CA227D24058534002D6750 /* VerizonNHGeDS-Regular.otf in Resources */,
D29DF32E21EE8C3D003B2FB9 /* Media.xcassets in Resources */,
942C372E241149170066E45E /* NHaasGroteskDSStd-75Bd.otf in Resources */,
942C372F241149170066E45E /* NHaasGroteskDSStd-55Rg.otf in Resources */,
94CA227E24058534002D6750 /* VerizonNHGeDS-Bold.otf in Resources */,
D29DF31B21ECECC0003B2FB9 /* OCRAExtended.ttf in Resources */,
);
@ -1708,6 +1847,7 @@
files = (
5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */,
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */,
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */,
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */,
94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */,
@ -1715,6 +1855,7 @@
D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */,
DBC4391822442197001AB423 /* CaretView.swift in Sources */,
C07065C42395677300FBF997 /* Link.swift in Sources */,
0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */,
D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */,
D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */,
D28A838923CCCFCB00DFE4FC /* LinkModel.swift in Sources */,
@ -1737,8 +1878,12 @@
D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */,
D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */,
D2B18B7F2360913400A9AEDC /* Control.swift in Sources */,
011D95A924057AC7000E3791 /* FormActionFieldProtocol.swift in Sources */,
D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */,
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */,
D29DF12F21E6851E003B2FB9 /* MVMCoreUITopAlertMainView.m in Sources */,
942C378C2412F4FA0066E45E /* ModalMoleculeListTemplate.swift in Sources */,
BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */,
012A88C8238DB02000FE3DA1 /* ModelMoleculeDelegateProtocol.swift in Sources */,
0A7EF86123D8AC2500B2AAD1 /* DigitEntryFieldModel.swift in Sources */,
DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */,
@ -1750,9 +1895,11 @@
9445891F2385D2E900DE9FD4 /* CaretViewModel.swift in Sources */,
01C851D323CF9E740021F976 /* LabelToggleModel.swift in Sources */,
D29DF2C521E7BF57003B2FB9 /* MFTabBarSwipeAnimator.m in Sources */,
011D95A3240453F8000E3791 /* RuleRegexModel.swift in Sources */,
D2E2A98323D8B32D000B42E6 /* EyebrowHeadlineBodyLinkModel.swift in Sources */,
012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */,
D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */,
011D9602240DA20A000E3791 /* ValidProtocol.swift in Sources */,
D260106323D0C05000764D80 /* StackItemModel.swift in Sources */,
D2E2A99823D8D63C000B42E6 /* ActionDetailWithImageModel.swift in Sources */,
D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */,
@ -1778,8 +1925,11 @@
012A88C4238D86E600FE3DA1 /* CarouselItemModelProtocol.swift in Sources */,
D2E2A9A123E095AB000B42E6 /* ButtonModelProtocol.swift in Sources */,
94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */,
D22D8395241FB41200D3DF69 /* UIStackView+Extension.swift in Sources */,
52B201D324081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift in Sources */,
525239C02407BCFF00454969 /* ListTwoColumnPriceDetailsModel.swift in Sources */,
D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */,
8D084AD22410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift in Sources */,
014AA73123C5059B006F3E93 /* ListPageTemplateModel.swift in Sources */,
017BEB4023620A230024EF95 /* TextFieldModel.swift in Sources */,
D29DF2A221E7AF4E003B2FB9 /* MVMCoreUIUtility.m in Sources */,
@ -1792,11 +1942,14 @@
AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */,
01EB369223609801006832FA /* MoleculeStackModel.swift in Sources */,
012CA99E2385A2D3003F810F /* MFView+ModelExtension.swift in Sources */,
011D9626240EBB16000E3791 /* RadioButtonLabelModel.swift in Sources */,
AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */,
D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */,
944589232385DA9600DE9FD4 /* ImageViewModel.swift in Sources */,
D213347723843825008E41B3 /* Line.swift in Sources */,
D28A837723C79FC600DFE4FC /* MFCustomButton+ActionModel.swift in Sources */,
D2E2A99C23D8D975000B42E6 /* ImageHeadlineBodyModel.swift in Sources */,
525019DE2406430800EED91C /* ListProgressBarData.swift in Sources */,
D28A837F23CCA96400DFE4FC /* TabsModel.swift in Sources */,
012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */,
D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */,
@ -1807,6 +1960,8 @@
DBEFFA04225A829700230692 /* Label.swift in Sources */,
D2D6CD4022E78C1A00D701B8 /* Scroller.swift in Sources */,
0A7EF85F23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift in Sources */,
011D959B240451E3000E3791 /* RuleRequiredModel.swift in Sources */,
526A265C240D1FF700B0D828 /* ListTwoColumnCompareChangesModel.swift in Sources */,
01509D952327ED1900EF99AA /* HeadlineBodyLinkToggle.swift in Sources */,
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */,
D260105523CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift in Sources */,
@ -1818,6 +1973,7 @@
0A1B4A96233BB18F005B3FB4 /* CheckboxLabel.swift in Sources */,
0A21DB8B235E06EF00C160A2 /* MFDigitTextBox.m in Sources */,
D260D7B222D65BDD007E7233 /* MVMCoreUIPageControl.m in Sources */,
BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */,
D2B18B812360945C00A9AEDC /* View.swift in Sources */,
C6FA7D5423C77A4A00A3614A /* NumberedList.swift in Sources */,
D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */,
@ -1837,7 +1993,7 @@
0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */,
D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */,
01EB368F23609801006832FA /* LabelModel.swift in Sources */,
0105618F224BBE7700E1557D /* FormValidator+FormParams.swift in Sources */,
942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */,
01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */,
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */,
011B58F023A2AA980085F53C /* ListItemModelProtocol.swift in Sources */,
@ -1850,7 +2006,9 @@
D29DF18321E69E54003B2FB9 /* SeparatorView.m in Sources */,
D29DF17A21E69E1F003B2FB9 /* MFCustomButton.m in Sources */,
017BEB7B236763000024EF95 /* LineModel.swift in Sources */,
D256E9932412880000360572 /* Header.swift in Sources */,
94C2D9A523872C350006CF46 /* LabelAttributeFontModel.swift in Sources */,
011D958724042492000E3791 /* FormFieldProtocol.swift in Sources */,
011D95AF2407266E000E3791 /* RadioButtonModel.swift in Sources */,
017BEB7F23676E870024EF95 /* MoleculeObjectMapping.swift in Sources */,
D274CA332236A78900B01B62 /* FooterView.swift in Sources */,
@ -1863,15 +2021,18 @@
944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */,
D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */,
C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */,
011D958524042432000E3791 /* RulesProtocol.swift in Sources */,
94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */,
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */,
526A265E240D200500B0D828 /* ListTwoColumnCompareChanges.swift in Sources */,
8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */,
D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */,
D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */,
012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */,
D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */,
9445890E2385C3F800DE9FD4 /* MultiProgressModel.swift in Sources */,
011D95A5240455DC000E3791 /* FormGroupRule.swift in Sources */,
D2A6390522CBCE160052ED1F /* MoleculeCollectionViewCell.swift in Sources */,
D2A6390122CBB1820052ED1F /* Carousel.swift in Sources */,
D29DF2C721E7BF57003B2FB9 /* MFTabBarInteractor.m in Sources */,
@ -1880,7 +2041,9 @@
D2FB151B23A2B65B00C20E10 /* MoleculeContainer.swift in Sources */,
D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */,
D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */,
AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */,
522679C223FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift in Sources */,
8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */,
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */,
8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */,
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
@ -1892,7 +2055,6 @@
D22D1F47220496A30077CEC0 /* MVMCoreUISwitch.m in Sources */,
C695A67F23C9830600BFB94E /* UnOrderedListModel.swift in Sources */,
0AE98BB523FF18D2004C5109 /* Arrow.swift in Sources */,
017BEB4223620AD20024EF95 /* FormModelProtocol.swift in Sources */,
D2D90B442404789000DD6EC9 /* MoleculeContainerProtocol.swift in Sources */,
012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */,
D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */,
@ -1900,11 +2062,10 @@
D29DF17B21E69E1F003B2FB9 /* PrimaryButton.m in Sources */,
017BEB4A236235BA0024EF95 /* ModelMoleculeViewProtocol.swift in Sources */,
C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */,
012CA99A2384A687003F810F /* MFTextField+ModelExtension.swift in Sources */,
01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */,
D27CD4102339057800C1DC07 /* EyebrowHeadlineBodyLink.swift in Sources */,
8D070BB2241B56AD0099AC56 /* ListRightVariableTotalData.swift in Sources */,
D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */,
0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */,
D243859923A16B1800332775 /* Container.swift in Sources */,
D2C521A923EDE79E00CA2634 /* ViewController.swift in Sources */,
D260105B23D0BB7100764D80 /* StackModelProtocol.swift in Sources */,
@ -1923,15 +2084,19 @@
94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */,
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */,
D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */,
011D9628240EFA1E000E3791 /* MFViewController+Form.swift in Sources */,
0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */,
52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */,
D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */,
0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */,
94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */,
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */,
011D95A1240453D0000E3791 /* RuleEqualsModel.swift in Sources */,
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
011D95892404249B000E3791 /* FormProtocol.swift in Sources */,
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */,
013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */,
525239C22407BD1000454969 /* ListTwoColumnPriceDetails.swift in Sources */,
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */,
D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */,
D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */,
@ -1951,13 +2116,14 @@
C7192E7D23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift in Sources */,
D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */,
D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */,
0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */,
0A7EF86323D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift in Sources */,
0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */,
D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */,
D2B18B922361E65A00A9AEDC /* CoreUIObject.swift in Sources */,
D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */,
014AA72E23C5059B006F3E93 /* StackCenteredPageTemplateModel.swift in Sources */,
D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */,
011D959D2404536F000E3791 /* RuleAnyValueChangedModel.swift in Sources */,
D260105923D0A92900764D80 /* ContainerProtocol.swift in Sources */,
C695A69423C9909000BFB94E /* DoughnutChartModel.swift in Sources */,
D29DF32421ED0DA2003B2FB9 /* TextButtonView.m in Sources */,
@ -1966,7 +2132,9 @@
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,
D2A514592211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m in Sources */,
94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */,
011D95AB2405C553000E3791 /* FormItemProtocol.swift in Sources */,
D21EE53C23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift in Sources */,
525019DD2406430800EED91C /* ListProgressBarDataModel.swift in Sources */,
C6FA7D5223C77A4A00A3614A /* UnOrderedList.swift in Sources */,
01509D8F2327EC6F00EF99AA /* MoleculeTableViewCell.swift in Sources */,
0105618D224BBE7700E1557D /* FormValidator.swift in Sources */,
@ -1974,7 +2142,8 @@
D22D1F1B220341F60077CEC0 /* MVMCoreUICheckBox.m in Sources */,
C695A69823C990C200BFB94E /* DoughnutChartView.swift in Sources */,
D29DF2CB21E7BFCC003B2FB9 /* MFSizeThreshold.m in Sources */,
946EE1BA237B66D80036751F /* MoleculeModelHelper.swift in Sources */,
011D959F240453A1000E3791 /* RuleAllValueChangedModel.swift in Sources */,
011D95AD2406BB57000E3791 /* FormHolderProtocol.swift in Sources */,
01509D932327ECFB00EF99AA /* ProgressBar.swift in Sources */,
D260106523D0CEA700764D80 /* StackModel.swift in Sources */,
D29770F521F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m in Sources */,

View File

@ -18,7 +18,8 @@ public enum ButtonSize: String, Codable {
case tiny
}
public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormActionFieldProtocol {
public static var identifier: String = "button"
public var backgroundColor: Color?
public var title: String
@ -32,9 +33,15 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
public var disabledFillColor: Color?
public var disabledTextColor: Color?
public var disabledBorderColor: Color?
public var required: Bool?
public var requiredGroups: [String]?
public var groupName: String? = FormValidator.defaultGroupName
public func updateEnable(_ enabled: Bool) {
self.enabled = enabled
updateUI?()
}
public var updateUI: (() -> Void)?
init(with title: String, action: ActionModelProtocol) {
self.title = title
self.action = action
@ -66,8 +73,7 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
case disabledFillColor
case disabledTextColor
case disabledBorderColor
case required
case requiredGroups
case groupName
}
required public init(from decoder: Decoder) throws {
@ -75,9 +81,10 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
title = try typeContainer.decode(String.self, forKey: .title)
action = try typeContainer.decodeModel(codingKey: .action, typeCodingKey: ActionCodingKey.actionType)
required = try typeContainer.decodeIfPresent(Bool.self, forKey: .required)
requiredGroups = try typeContainer.decodeIfPresent([String].self, forKey: .requiredGroups)
action = try typeContainer.decodeModel(codingKey: .action)
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
self.groupName = groupName
}
if let style = try typeContainer.decodeIfPresent(ButtonStyle.self, forKey: .style) {
self.style = style
}
@ -110,7 +117,6 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
try container.encodeIfPresent(disabledFillColor, forKey: .disabledFillColor)
try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor)
try container.encodeIfPresent(disabledBorderColor, forKey: .disabledBorderColor)
try container.encodeIfPresent(required, forKey: .required)
try container.encodeIfPresent(requiredGroups, forKey: .requiredGroups)
try container.encodeIfPresent(groupName, forKey: .groupName)
}
}

View File

@ -46,7 +46,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol {
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
self.enabled = enabled
}
action = try typeContainer.decodeModel(codingKey: .action, typeCodingKey: ActionCodingKey.actionType)
action = try typeContainer.decodeModel(codingKey: .action)
}
public func encode(to encoder: Encoder) throws {

View File

@ -36,6 +36,13 @@ import UIKit
context?.strokePath()
}
open override var intrinsicContentSize: CGSize {
guard let size = titleLabel?.intrinsicContentSize else {
return super.intrinsicContentSize
}
return CGSize(width: size.width, height: size.height + 2)
}
//--------------------------------------------------
// MARK: - ModelMoleculeViewProtocol
//--------------------------------------------------
@ -81,6 +88,7 @@ extension Link {
titleLabel?.lineBreakMode = .byTruncatingTail
titleLabel?.textAlignment = .left
contentHorizontalAlignment = .left
contentVerticalAlignment = .top
}
}

View File

@ -55,7 +55,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
title = try typeContainer.decode(String.self, forKey: .title)
action = try typeContainer.decodeModel(codingKey: .action, typeCodingKey: ActionCodingKey.actionType)
action = try typeContainer.decodeModel(codingKey: .action)
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
self.enabled = enabled

View File

@ -8,7 +8,7 @@
import UIKit
open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidationEnableDisableProtocol {
open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
// Used to size the button.
var size = MVMCoreUIUtility.getWidth()
@ -125,11 +125,12 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation
guard let model = model as? ButtonModel else { return }
setTitle(model.title, for: .normal)
if let required = model.required,
required {
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
model.updateUI = { [weak self] in
self?.enableField(model.enabled)
}
FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
@ -163,17 +164,8 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation
open func horizontalAlignment() -> UIStackView.Alignment {
return .center
}
// MARK: - FormValidationEnableDisableProtocol
public func isValidationRequired() -> Bool {
return buttonModel?.required ?? false
}
public func requiredGroups() -> [String]? {
return buttonModel?.requiredGroups
}
public func enableField(_ enable: Bool) {
isEnabled = isValidationRequired() ? enable : true
isEnabled = enable
}
}

View File

@ -16,14 +16,6 @@ extension PrimaryButton: ModelMoleculeViewProtocol {
setTitle(model.title, for: .normal)
backgroundColor = model.backgroundColor?.uiColor
self.validationRequired = model.required ?? false
self.requiredGroupsList = model.requiredGroups
if self.validationRequired,
let selfForm = self as? FormValidationEnableDisableProtocol {
FormValidator.setupValidation(molecule: selfForm, delegate: delegateObject?.formValidationProtocol)
}
if let style = model.style {
switch style {
case .primary:

View File

@ -48,8 +48,6 @@ import UIKit
//--------------------------------------------------
public var isValid: Bool = false
public var fieldKey: String?
public var errorMessage: String?
public var standardMessage: String? {
didSet {
@ -259,10 +257,6 @@ import UIKit
} else if let isSelected = model.isSelected{
self.isSelected = isSelected
}
if let fieldKey = model.fieldKey {
self.fieldKey = fieldKey
}
}
}
@ -300,11 +294,6 @@ extension EntryField {
if let isSelected = dictionary["isSelected"] as? Bool {
self.isSelected = isSelected
}
// Key used to send text value to server
if let fieldKey = dictionary[KeyFieldKey] as? String {
self.fieldKey = fieldKey
}
}
@objc open class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
@ -312,22 +301,6 @@ extension EntryField {
}
}
// MARK: - Form Validation
extension EntryField: FormValidationProtocol {
@objc public func isValidField() -> Bool {
return isValid
}
@objc public func formFieldName() -> String? {
return fieldKey
}
@objc public func formFieldValue() -> Any? {
return text
}
}
// MARK: - Accessibility
extension EntryField {

View File

@ -9,7 +9,8 @@
import Foundation
@objcMembers public class EntryFieldModel: MoleculeModelProtocol {
@objcMembers public class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, ValidProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
@ -26,8 +27,19 @@ import Foundation
public var isLocked: Bool?
public var isSelected: Bool?
public var fieldKey: String?
public var isValid: Bool?
public var isRequired: Bool?
public var groupName: String? = FormValidator.defaultGroupName
public var text: String?
public var baseValue: AnyHashable?
public var isValid: Bool? {
didSet {
updateUI?()
}
}
public var updateUI: (() -> Void)?
public func setValidity(_ isValid: Bool) {
self.isValid = isValid
}
//--------------------------------------------------
// MARK: - Keys
@ -45,6 +57,12 @@ import Foundation
case fieldKey
case isValid
case isRequired = "required"
case text
case groupName
}
public func formFieldValue() -> AnyHashable? {
return text
}
//--------------------------------------------------
@ -62,6 +80,11 @@ import Foundation
isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .isSelected)
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
isValid = try typeContainer.decodeIfPresent(Bool.self, forKey: .isValid)
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
self.groupName = groupName
}
}
public func encode(to encoder: Encoder) throws {
@ -76,5 +99,7 @@ import Foundation
try container.encode(isSelected, forKey: .isSelected)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(isValid, forKey: .isValid)
try container.encodeIfPresent(text, forKey: .text)
try container.encodeIfPresent(groupName, forKey: .groupName)
}
}

View File

@ -1,79 +0,0 @@
//
// MFTextField+ModelExtension.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 11/19/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import UIKit
enum TextType: String {
case dropDown = "dropDown"
case password = "password"
case number = "number"
case email = "email"
}
extension MFTextField: ModelMoleculeViewProtocol {
//
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
//TODO: Need to create setWithModel in ViewConstraining View
#warning("This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView.")
//TODO: This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView.
setUpDefaultWithModel(model, delegateObject, additionalData)
guard let textFieldModel = model as? TextFieldModel,
let delegateObject = delegateObject else {
return
}
if let delegate = delegateObject.formValidationProtocol {
let formValidator = FormValidator.getFormValidatorFor(delegate: delegate)
mfTextFieldDelegate = formValidator
uiTextFieldDelegate = delegateObject.uiTextFieldDelegate
if let textField = textField {
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate)
}
}
formText = textFieldModel.label as NSString?
text = textFieldModel.value as NSString?
if let disabled = textFieldModel.disabled {
enable(disabled)
}
errMessage = textFieldModel.errorMsg
fieldKey = textFieldModel.fieldKey
groupName = textFieldModel.groupName
switch textFieldModel.type {
case TextType.dropDown.rawValue:
dropDownCarrotLabel?.isHidden = true
hasDropDown = true
break
case TextType.password.rawValue:
textField?.isSecureTextEntry = true
break
case TextType.number.rawValue:
textField?.keyboardType = .numberPad
break
case TextType.email.rawValue:
textField?.keyboardType = .emailAddress
break
default:
print("default")
}
if let regex = textFieldModel.regex {
validationBlock = {(enteredValue: String?) -> Bool in
if let enteredValue = enteredValue {
return MVMCoreUIUtility.validate(enteredValue, withRegularExpression: regex)
}
return true
}
} else {
setDefaultValidationBlock()
}
}
}

View File

@ -97,24 +97,24 @@ import MVMCore
return MVMCoreUIUtility.validateInternationalMDNString(MDN)
}
@objc public override func validateTextField() -> Bool {
@objc public func validateMDNTextField() -> Bool {
guard !shouldValidateMDN, let MDN = mdn, !MDN.isEmpty else {
isValid = true
return true
}
let isValid = hasValidMDN()
if isValid {
showError = false
} else {
errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
showError = true
UIAccessibility.post(notification: .layoutChanged, argument: textField)
}
return isValid
}
@ -186,7 +186,7 @@ import MVMCore
proprietorTextDelegate?.textFieldDidEndEditing?(textField)
if validateTextField() && isNationalMDN {
if validateMDNTextField() && isNationalMDN {
textField.text = MVMCoreUIUtility.formatMdn(textField.text)
}
}

View File

@ -44,12 +44,12 @@ import UIKit
private var observingForChange: Bool = false
/// Validate on each entry in the textField. Default: false
public var validateEachCharacter: Bool = false
/// Validate on each entry in the textField. Default: true
public var validateEachCharacter: Bool = true
/// Validate when user resigns editing. Default: true
public var validateWhenDoneEditing: Bool = true
//--------------------------------------------------
// MARK: - Computed Properties
//--------------------------------------------------
@ -197,9 +197,8 @@ import UIKit
@objc deinit {
setBothTextDelegates(to: nil)
}
@objc public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
observingTextFieldDelegate = delegate
uiTextFieldDelegate = delegate
}
@ -218,62 +217,55 @@ import UIKit
@discardableResult
@objc override open func resignFirstResponder() -> Bool {
if validateWhenDoneEditing {
validateTextField()
}
textField.resignFirstResponder()
isSelected = false
return true
}
/// Validates the text of the entry field.
@discardableResult
@objc public func validateTextField() -> Bool {
isValid = validationBlock?(text) ?? true
if isValid {
showError = false
observingTextFieldDelegate?.isValid?(textfield: self)
} else {
@objc public func validateTextField() {
text = textField.text
FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
}
@objc public func updateValidation(_ isValid: Bool) {
let previousValidity = self.isValid
self.isValid = isValid
if previousValidity && !isValid {
showError = true
observingTextFieldDelegate?.isInvalid?(textfield: self)
} else if (!previousValidity && isValid) {
showError = false
observingTextFieldDelegate?.isValid?(textfield: self)
}
return isValid
}
/// Executes on UITextField.textDidBeginEditingNotification
@objc func startEditing() {
isSelected = true
textField.becomeFirstResponder()
}
/// Executes on UITextField.textDidChangeNotification (each character entry)
@objc func valueChanged() {
guard validateEachCharacter else { return }
isSelected = true
validateTextField()
}
/// Executes on UITextField.textDidEndEditingNotification
@objc func endInputing() {
resignFirstResponder()
if isValid {
showError = false
entryFieldContainer.bottomBar?.backgroundColor = UIColor.black.cgColor
}
resignFirstResponder()
}
@objc func dismissFieldInput(_ sender: Any?) {
resignFirstResponder()
}
@ -281,9 +273,14 @@ import UIKit
super.set(with: model, delegateObject, additionalData)
guard let model = model as? TextEntryFieldModel else { return }
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
model.updateUI = { [weak self] in
if self?.isSelected ?? false {
self?.updateValidation(model.isValid ?? true)
}
}
self.delegateObject = delegateObject
FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate)
textColor.enabled = model.enabledTextColor?.uiColor
textColor.disabled = model.disabledTextColor?.uiColor
text = model.text
@ -312,11 +309,8 @@ import UIKit
defaultValidationBlock()
}
if let formValidationProtocol = delegateObject?.formValidationProtocol {
observingTextFieldDelegate = FormValidator.getFormValidatorFor(delegate: formValidationProtocol)
}
uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate
observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate)
}
}
@ -330,9 +324,7 @@ extension TextEntryField {
guard let delegateObject = delegateObject,
let dictionary = json
else { return }
FormValidator.setupValidation(molecule: self, delegate: delegateObject.formValidationProtocol)
if let enabledTextColorHex = dictionary["enabledTextColor"] as? String {
textColor.enabled = UIColor.mfGet(forHex: enabledTextColorHex)
}
@ -374,11 +366,9 @@ extension TextEntryField {
defaultValidationBlock()
}
if let formValidationProtocol = delegateObject.formValidationProtocol {
observingTextFieldDelegate = FormValidator.getFormValidatorFor(delegate: formValidationProtocol)
}
uiTextFieldDelegate = delegateObject.uiTextFieldDelegate
observingTextFieldDelegate = delegateObject.observingTextFieldDelegate
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate)
}
}

View File

@ -16,7 +16,6 @@
return "textField"
}
public var text: String?
public var placeholder: String?
public var enabledTextColor: Color?
public var disabledTextColor: Color?

View File

@ -8,7 +8,7 @@
import UIKit
@objcMembers public class TextFieldModel: MoleculeModelProtocol, FormModelProtocol {
@objcMembers public class TextFieldModel: MoleculeModelProtocol {
public static var identifier: String = "textField"
public var backgroundColor: Color?

View File

@ -19,9 +19,8 @@ import MVMCore
public var sizeObject: MFSizeObject? = MFSizeObject(standardSize: Checkbox.defaultHeightWidth, standardiPadPortraitSize: Checkbox.defaultHeightWidth + 6.0)
// Form Validation
var isRequired = false
var fieldKey: String?
var fieldValue: String?
var fieldValue: JSONValue?
var groupName: String?
var delegateObject: MVMCoreUIDelegateObject?
@ -127,9 +126,10 @@ import MVMCore
didSet {
if !updateSelectionOnly {
layoutIfNeeded()
(model as? CheckboxModel)?.isChecked = isSelected
shapeLayer?.removeAllAnimations()
updateCheckboxUI(isSelected: isSelected, isAnimated: isAnimated)
FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol)
FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
updateAccessibilityLabel()
}
}
@ -398,75 +398,11 @@ import MVMCore
//layoutIfNeeded()
}
public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
self.delegateObject = delegateObject
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
guard let dictionary = json else { return }
groupName = dictionary.optionalStringForKey("groupName")
fieldValue = dictionary.optionalStringForKey("value")
if let fieldKey = dictionary[KeyFieldKey] as? String {
self.fieldKey = fieldKey
}
if let isRequired = dictionary[KeyRequired] as? Bool {
self.isRequired = isRequired
}
if let borderColorHex = dictionary["borderColor"] as? String {
layer.borderColor = UIColor.mfGet(forHex: borderColorHex).cgColor
}
if let borderWidth = dictionary["borderWidth"] as? CGFloat {
layer.borderWidth = borderWidth
}
if let checkColorHex = dictionary["checkColor"] as? String {
checkColor = UIColor.mfGet(forHex: checkColorHex)
}
if let isChecked = dictionary["isChecked"] as? Bool, isChecked {
checkAndBypassAnimations(selected: isChecked)
}
if let unCheckedBackgroundColorHex = dictionary["unCheckedBackgroundColor"] as? String {
unCheckedBackgroundColor = UIColor.mfGet(forHex: unCheckedBackgroundColorHex)
}
if let checkedBackgroundColorHex = dictionary["checkedBackgroundColor"] as? String {
checkedBackgroundColor = UIColor.mfGet(forHex: checkedBackgroundColorHex)
}
if let isAnimated = dictionary["isAnimated"] as? Bool {
self.isAnimated = isAnimated
}
if let isRound = dictionary["isRound"] as? Bool {
self.isRound = isRound
}
if let enabled = dictionary["isEnabled"] as? Bool {
isEnabled = enabled
}
if let actionMap = dictionary.optionalDictionaryForKey("action") {
actionBlock = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) }
}
}
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? CheckboxModel else { return }
self.delegateObject = delegateObject
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
groupName = model.groupName
fieldValue = model.value
isRequired = model.required
FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate)
if let fieldKey = model.fieldKey {
self.fieldKey = fieldKey
@ -500,23 +436,3 @@ import MVMCore
}
}
}
// MARK:- FormValidationProtocol
extension Checkbox: FormValidationFormFieldProtocol {
public func formFieldGroupName() -> String? {
return groupName
}
public func isValidField() -> Bool {
return isRequired ? isSelected : true
}
public func formFieldName() -> String? {
return fieldKey
}
public func formFieldValue() -> Any? {
return isSelected ? fieldValue : nil
}
}

View File

@ -8,69 +8,71 @@
import Foundation
@objcMembers public class CheckboxModel: MoleculeModelProtocol {
@objcMembers public class CheckboxModel: MoleculeModelProtocol, FormFieldProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "checkbox"
public var backgroundColor: Color?
public var groupName: String?
public var value: String?
public var fieldKey: String?
public var required: Bool = false
public var borderColor: Color = Color(uiColor: .black)
public var borderWidth: CGFloat = 1
public var isChecked: Bool = false
public var isEnabled: Bool = true
public var isAnimated: Bool = true
public var isRound: Bool = false
public var borderWidth: CGFloat = 1
public var borderColor: Color = Color(uiColor: .black)
public var checkColor: Color = Color(uiColor: .black)
public var unCheckedBackgroundColor: Color = Color(uiColor: .clear)
public var checkedBackgroundColor: Color = Color(uiColor: .clear)
public var isAnimated: Bool = true
public var isRound: Bool = false
public var isEnabled: Bool = true
public var action: ActionModelProtocol?
public var disabledBackgroundColor: Color = Color(uiColor: .clear)
public var disabledBorderColor: Color = Color(uiColor: .mvmCoolGray3)
public var disabledCheckColor: Color = Color(uiColor: .mvmCoolGray3)
public var action: ActionModelProtocol?
public var fieldKey: String?
public var fieldValue: JSONValue?
public var groupName: String? = FormValidator.defaultGroupName
public var baseValue: AnyHashable?
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case groupName
case value
case fieldKey
case required
case borderColor
case fieldValue
case isChecked = "checked"
case isEnabled = "enabled"
case isAnimated = "animated"
case isRound = "round"
case borderWidth
case isChecked
case borderColor
case checkColor
case unCheckedBackgroundColor
case checkedBackgroundColor
case disabledBackgroundColor
case disabledCheckColor
case disabledBorderColor
case isAnimated
case isRound
case isEnabled
case action
case groupName
}
init(isChecked: Bool = false) {}
public func formFieldValue() -> AnyHashable? {
return isChecked
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName)
value = try typeContainer.decodeIfPresent(String.self, forKey: .value)
fieldValue = try typeContainer.decodeIfPresent(JSONValue.self, forKey: .fieldValue)
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
required = try typeContainer.decodeIfPresent(Bool.self, forKey: .required) ?? false
borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) ?? 1
borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) ?? Color(uiColor: .black)
checkColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkColor) ?? Color(uiColor: .black)
@ -83,16 +85,18 @@ import Foundation
isAnimated = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAnimated) ?? true
isRound = try typeContainer.decodeIfPresent(Bool.self, forKey: .isRound) ?? false
isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEnabled) ?? true
action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType)
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
self.groupName = groupName
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(groupName, forKey: .groupName)
try container.encodeIfPresent(value, forKey: .value)
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(required, forKey: .required)
try container.encodeIfPresent(borderColor, forKey: .borderColor)
try container.encode(borderWidth, forKey: .borderWidth)
try container.encode(isChecked, forKey: .isChecked)
@ -106,5 +110,6 @@ import Foundation
try container.encodeIfPresent(isRound, forKey: .isRound)
try container.encodeIfPresent(isEnabled, forKey: .isEnabled)
try container.encodeModelIfPresent(action, forKey: .action)
try container.encodeIfPresent(groupName, forKey: .groupName)
}
}

View File

@ -25,7 +25,7 @@ open class LabelAttributeActionModel: LabelAttributeModel {
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
action = try typeContainer.decodeModel(codingKey: .action, typeCodingKey: ActionCodingKey.actionType)
action = try typeContainer.decodeModel(codingKey: .action)
try super.init(from: decoder)
}

View File

@ -32,7 +32,7 @@ import Foundation
var location: Int
var length: Int
init(_ location: Int, _ length: Int) {
public init(_ location: Int, _ length: Int) {
self.location = location
self.length = length
}

View File

@ -19,4 +19,8 @@ import UIKit
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
}
public override init(_ location: Int, _ length: Int) {
super.init(location, length)
}
}

View File

@ -74,7 +74,7 @@ import Foundation
fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName)
fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize)
textAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .textAlignment)
attributes = try typeContainer.decodeModelsIfPresent(codingKey: .attributes, typeCodingKey: AttributeTypeKey.type) as? [LabelAttributeModel]
attributes = try typeContainer.decodeModelsIfPresent(codingKey: .attributes)
html = try typeContainer.decodeIfPresent(String.self, forKey: .html)
hero = try typeContainer.decodeIfPresent(Int.self, forKey: .hero)
makeWholeViewClickable = try typeContainer.decodeIfPresent(Bool.self, forKey: .makeWholeViewClickable)
@ -91,10 +91,7 @@ import Foundation
try container.encodeIfPresent(fontName, forKey: .fontName)
try container.encodeIfPresent(fontSize, forKey: .fontSize)
try container.encodeIfPresent(textAlignment, forKey: .textAlignment)
var attributeContainer = container.nestedUnkeyedContainer(forKey: .attributes)
try attributes?.forEach { attributeModel in
try attributeContainer.encode(attributeModel)
}
try container.encodeModelsIfPresent(attributes, forKey: .attributes)
try container.encodeIfPresent(html, forKey: .html)
try container.encodeIfPresent(hero, forKey: .hero)
try container.encodeIfPresent(makeWholeViewClickable, forKey: .makeWholeViewClickable)

View File

@ -81,7 +81,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
return NSRange(location: 0, length: frontText?.count ?? 0)
}
private var actionRange: NSRange {
public var actionRange: NSRange {
return NSRange(location: frontText?.count ?? 0, length: actionText?.count ?? 0)
}

View File

@ -8,14 +8,22 @@
import UIKit
@objcMembers public class LeftRightLabelModel: MoleculeModelProtocol {
@objcMembers open class LeftRightLabelModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "leftRightLabelView"
public var moleculeName: String? = LeftRightLabelModel.identifier
public var backgroundColor: Color?
public var leftText: LabelModel
public var rightText: LabelModel?
init(_ leftText: LabelModel) {
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(_ leftText: LabelModel) {
self.leftText = leftText
}
}

View File

@ -181,7 +181,7 @@ import UIKit
let widthWillChange = !MVMCoreGetterUtility.cgfequal(widthConstraint?.constant ?? 0, width ?? 0)
let heightWillChange = !MVMCoreGetterUtility.cgfequal(heightConstraint?.constant ?? 0, height ?? 0)
let sizeWillChange = (width == nil || height == nil) && !(size?.equalTo(imageView.image?.size ?? CGSize.zero) ?? false)
let heightChangeFromSpinner = ((height ?? size?.height) ?? 0) < loadingSpinnerHeightConstraint?.constant ?? CGFloat.leastNormalMagnitude
let heightChangeFromSpinner = (heightConstraint?.isActive ?? false) ? false : ((height ?? size?.height) ?? 0) < loadingSpinnerHeightConstraint?.constant ?? CGFloat.leastNormalMagnitude
return widthWillChange || heightWillChange || sizeWillChange || heightChangeFromSpinner
}

View File

@ -18,7 +18,7 @@ extension MFView {
}
extension ModelMoleculeViewProtocol where Self: MFView {
func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
setUpDefaultWithModel(model, delegateObject, additionalData)
}
}

View File

@ -13,10 +13,7 @@ extension MVMCoreUISwitch: ModelMoleculeViewProtocol {
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
guard let model = model as? ToggleModel else { return }
if let castSelf = self as? FormValidationProtocol {
FormValidator.setupValidation(molecule: castSelf, delegate: delegateObject?.formValidationProtocol)
}
FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate)
setState(model.state, animated: false)
guard let action = model.action else { return }

View File

@ -8,34 +8,33 @@
import UIKit
@objcMembers public class RadioButton: Control, FormValidationFormFieldProtocol {
@objcMembers public class RadioButton: Control {
var diameter: CGFloat = 30 {
didSet {
widthConstraint?.constant = diameter
}
}
var enabledColor = UIColor.black
var disabledColor = UIColor.mfSilver()
var disabledColor = UIColor.mfSilver()
var delegateObject: MVMCoreUIDelegateObject?
var fieldKey: String?
var formValue: Bool?
var isRequired: Bool = false
var widthConstraint: NSLayoutConstraint?
var heightConstraint: NSLayoutConstraint?
var radioModel: RadioButtonModel? {
return model as? RadioButtonModel
}
lazy var radioGroupName: String? = {
[unowned self] in
return json?.optionalStringForKey("radioGroupName") ?? json?.optionalStringForKey("fieldKey")
[unowned self] in return radioModel?.fieldKey
}()
lazy var radioButtonModel: RadioButtonSelectionHelper? = {
lazy var radioButtonSelectionHelper: RadioButtonSelectionHelper? = {
[unowned self] in
if let radioGroupName = radioGroupName,
let radioButtonModel = delegateObject?.formValidationProtocol?.formValidatorModel?()?.radioButtonsModelByGroup[radioGroupName] {
let radioButtonModel = delegateObject?.formHolderDelegate?.formValidator?.radioButtonsModelByGroup[radioGroupName] {
return radioButtonModel
} else {
return nil
@ -58,12 +57,12 @@ import UIKit
/// The action performed when tapped.
func tapAction() {
if let radioButtonModel = radioButtonModel {
if let radioButtonModel = radioButtonSelectionHelper {
radioButtonModel.selected(self)
} else {
isSelected = !isSelected
}
FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol)
FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
setNeedsDisplay()
}
@ -72,15 +71,15 @@ import UIKit
}
public func formFieldName() -> String? {
return json?.optionalStringForKey("fieldKey")
return radioModel?.fieldKey
}
public func formFieldGroupName() -> String? {
return json?.optionalStringForKey("groupName")
return radioModel?.fieldKey
}
public func formFieldValue() -> Any? {
return isSelected
public func formFieldValue() -> AnyHashable? {
return radioModel?.fieldValue
}
// MARK: - MVMViewProtocol
@ -104,40 +103,14 @@ import UIKit
guard let model = model as? RadioButtonModel else {
return
}
setWithJSON(model.toJSON(), delegateObject: delegateObject, additionalData: additionalData)
}
}
// MARK: - MVMCoreUIViewConstrainingProtocol
extension RadioButton: MVMCoreUIViewConstrainingProtocol {
public func needsToBeConstrained() -> Bool {
return true
}
}
// MARK: - MVMCoreUIMoleculeViewProtocol
extension RadioButton {
@objc open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
// Configure class properties with JSON values
guard let jsonDictionary = json else {
return
}
fieldKey = jsonDictionary.optionalStringForKey("fieldKey")
isRequired = jsonDictionary.boolForKey("required")
self.delegateObject = delegateObject
let radioButtonModel = RadioButtonSelectionHelper.setupForRadioButtonGroup(radioButton: self,
formValidator: delegateObject?.formValidationProtocol?.formValidatorModel?())
FormValidator.setupValidation(molecule: radioButtonModel, delegate: delegateObject?.formValidationProtocol)
let radioButtonModel = RadioButtonSelectionHelper.setupForRadioButtonGroup(model,
formValidator: delegateObject?.formHolderDelegate?.formValidator)
FormValidator.setupValidation(molecule: radioButtonModel, delegate: delegateObject?.formHolderDelegate)
}
public override func reset() {
super.reset()
backgroundColor = .white
super.reset()
backgroundColor = .white
}
}

View File

@ -7,11 +7,60 @@
//
import Foundation
import MVMCore
public class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol {
public class RadioButtonModel: MoleculeModelProtocol {
public static var identifier: String = "radioButton"
public var backgroundColor: Color?
public var state: Bool = false
public var enabled: Bool = true
public var baseValue: AnyHashable?
public var groupName: String?
public var fieldKey: String?
public var fieldValue: String?
private enum CodingKeys: String, CodingKey {
case moleculeName
case backgroundColor
case state
case enabled
case fieldKey
case fieldValue
case groupName
}
public init(_ state: Bool) {
self.state = state
}
public func formFieldValue() -> AnyHashable? {
return state
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) {
self.state = state
}
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
self.enabled = enabled
}
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName)
fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(state, forKey: .state)
try container.encode(enabled, forKey: .enabled)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(groupName, forKey: .groupName)
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
}
}

View File

@ -19,7 +19,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
Container: The background of the toggle control.
Knob: The circular indicator that slides on the container.
*/
@objcMembers open class Toggle: Control, MVMCoreUIViewConstrainingProtocol, FormValidationFormFieldProtocol {
@objcMembers open class Toggle: Control, MVMCoreUIViewConstrainingProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
@ -100,8 +100,9 @@ public typealias ActionBlockConfirmation = () -> (Bool)
knobView.backgroundColor = isOn ? knobTintColor?.on : knobTintColor?.off
self.constrainKnob()
}
FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol)
(model as? ToggleModel)?.state = isOn
FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
accessibilityValue = isOn ? MVMCoreUIUtility.hardcodedString(withKey: "AccOn") : MVMCoreUIUtility.hardcodedString(withKey: "AccOff")
setNeedsLayout()
layoutIfNeeded()
@ -339,82 +340,61 @@ public typealias ActionBlockConfirmation = () -> (Bool)
return
}
self.model = model
self.delegateObject = delegateObject
let toggleModelJSON = toggleModel.toJSON()
FormValidator.setupValidation(molecule: toggleModel, delegate: delegateObject?.formHolderDelegate)
setWithJSON(toggleModelJSON, delegateObject: delegateObject, additionalData: additionalData)
}
//TODO: change to setWith Model
public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
guard let dictionary = json else { return }
if let color = dictionary["onTintColor"] as? String {
containerTintColor?.on = UIColor.mfGet(forHex: color)
}
if let color = dictionary["offTintColor"] as? String {
containerTintColor?.off = UIColor.mfGet(forHex: color)
}
if let color = dictionary["onKnobTintColor"] as? String {
knobTintColor?.on = UIColor.mfGet(forHex: color)
}
if let color = dictionary["offKnobTintColor"] as? String {
knobTintColor?.off = UIColor.mfGet(forHex: color)
}
if let state = dictionary["state"] as? Bool {
changeStateNoAnimation(state)
}
if let actionMap = dictionary.optionalDictionaryForKey("action") {
didToggleAction = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) }
}
if let isAnimated = dictionary["isAnimated"] as? Bool {
self.isAnimated = isAnimated
}
if let isEnabled = dictionary["isEnabled"] as? Bool{
self.isEnabled = isEnabled
}
}
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return Self.getContainerHeight()
}
}
// MARK: - Accessibility
extension Toggle {
public func formFieldGroupName() -> String? {
return json?["groupName"] as? String
}
}
// MARK: - FormValidationProtocol
extension Toggle {
public func isValidField() -> Bool {
return isOn && json?["required"] as? Bool ?? false
}
public func formFieldName() -> String? {
return json?[KeyFieldKey] as? String ?? ""
}
public func formFieldValue() -> Any? {
return NSNumber(value: isOn)
}
}
// MARK: - MVMCoreUIMoleculeViewProtocol
extension Toggle {
public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
self.delegateObject = delegateObject
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
guard let dictionary = json else { return }
if let color = dictionary["onTintColor"] as? String {
containerTintColor?.on = UIColor.mfGet(forHex: color)
}
if let color = dictionary["offTintColor"] as? String {
containerTintColor?.off = UIColor.mfGet(forHex: color)
}
if let color = dictionary["onKnobTintColor"] as? String {
knobTintColor?.on = UIColor.mfGet(forHex: color)
}
if let color = dictionary["offKnobTintColor"] as? String {
knobTintColor?.off = UIColor.mfGet(forHex: color)
}
if let state = dictionary["state"] as? Bool {
changeStateNoAnimation(state)
}
if let actionMap = dictionary.optionalDictionaryForKey("action") {
didToggleAction = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) }
}
if let isAnimated = dictionary["isAnimated"] as? Bool {
self.isAnimated = isAnimated
}
if let isEnabled = dictionary["isEnabled"] as? Bool{
self.isEnabled = isEnabled
}
}
public class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
return Self.getContainerHeight()

View File

@ -8,23 +8,29 @@
import UIKit
public class ToggleModel: MoleculeModelProtocol {
public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol {
public static var identifier: String = "toggle"
public var backgroundColor: Color?
public var state: Bool = true
public var action: ActionModelProtocol?
public var alternateAction: ActionModelProtocol?
public var required: Bool?
public var fieldKey: String?
public var groupName: String? = FormValidator.defaultGroupName
public var baseValue: AnyHashable?
private enum CodingKeys: String, CodingKey {
case moleculeName
case state
case action
case backgroundColor
case required
case fieldKey
case alternateAction
case groupName
}
public func formFieldValue() -> AnyHashable? {
return state
}
public init(_ state: Bool) {
@ -36,11 +42,13 @@ public class ToggleModel: MoleculeModelProtocol {
if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) {
self.state = state
}
action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType)
alternateAction = try typeContainer.decodeModelIfPresent(codingKey: .alternateAction, typeCodingKey: ActionCodingKey.actionType)
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
alternateAction = try typeContainer.decodeModelIfPresent(codingKey: .alternateAction)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
required = try typeContainer.decodeIfPresent(Bool.self, forKey: .required)
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
self.groupName = groupName
}
}
public func encode(to encoder: Encoder) throws {
@ -49,8 +57,8 @@ public class ToggleModel: MoleculeModelProtocol {
try container.encodeModelIfPresent(action, forKey: .action)
try container.encodeModelIfPresent(alternateAction, forKey: .alternateAction)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(state, forKey: .state)
try container.encodeIfPresent(required, forKey: .required)
try container.encode(state, forKey: .state)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(groupName, forKey: .groupName)
}
}

View File

@ -120,7 +120,7 @@ import UIKit
}
// MARK: - MFViewProtocol
public func updateView(_ size: CGFloat) {
open func updateView(_ size: CGFloat) {
containerHelper.updateViewMargins(self, model: listItemModel, size: size)
if accessoryView != nil {
@ -151,7 +151,7 @@ import UIKit
}
//TODO: ModelProtocol, Change to model
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let model = model as? ListItemModelProtocol else { return }
self.listItemModel = model
@ -176,6 +176,9 @@ import UIKit
let backgroundColor = moleculeModel.backgroundColor {
self.backgroundColor = backgroundColor.uiColor
}
// align if needed.
containerHelper.set(with: model, for: molecule as? MVMCoreUIViewConstrainingProtocol)
}
open func reset() {
@ -183,11 +186,11 @@ import UIKit
backgroundColor = .white
}
public class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
open class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
return model.moleculeName
}
public class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return nil
}

View File

@ -0,0 +1,22 @@
//
// MFViewController+Form.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 3/3/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
extension MFViewController: ObservingTextFieldDelegate {
}
public extension MFViewController {
@objc func startValidation() {
(self as? FormHolderProtocol)?.formValidator?.validate()
}
@objc func addFormParams(requestParameters: MVMCoreRequestParameters) {
(self as? FormHolderProtocol)?.formValidator?.addFormParams(requestParameters: requestParameters)
}
}

View File

@ -31,9 +31,10 @@ extension MFViewController: MoleculeDelegateProtocol {
return nil
}
@objc public func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) { }
// These are required because swift will call the extension function otherwise.
@objc public func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) {}
@objc public func addMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { }
@objc public func removeMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { }
@objc public func addMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {}
@objc public func addMolecules(_ molecules: [[AnyHashable : Any]], indexPath: IndexPath, animation: UITableView.RowAnimation) {}
@objc public func removeMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {}
}

View File

@ -38,7 +38,7 @@
#import <MVMCoreUI/MVMCoreUI-Swift.h>
@import MVMAnimationFramework;
@interface MFViewController() <FormValidationProtocol>
@interface MFViewController()
// A flag for if this view controller is observing for cache updates or not.
@property (nonatomic) BOOL observingForResponseJSONUpdates;
@ -52,19 +52,10 @@
// title view for navigation bar, used for custom navigation titles
@property (weak, nonatomic) UILabel *titleLabel;
@property (strong, nonatomic) FormValidator *formValidator;
@end
@implementation MFViewController
- (FormValidator *)formValidatorModel {
if (self.formValidator == nil) {
self.formValidator = [FormValidator new];
}
return self.formValidator;
}
- (void)dismiss {
[MVMCoreDispatchUtility performBlockOnMainThread:^{
if (self.presentingViewController) {
@ -477,7 +468,7 @@
// Since we have new data, build stuff for the screen and update the ui once the screen is done laying out.
[self newDataBuildAndUpdate];
self.needToupdateUIOnScreenSizeChanges = YES;
if (UIAccessibilityIsVoiceOverRunning()) {
@ -487,12 +478,13 @@
if (!self.disableAnimations) {
[self setupIntroAnimations];
}
}
- (void)newDataBuildAndUpdate {
[MVMCoreDispatchUtility performBlockOnMainThread:^{
[self newDataBuildScreen];
[self.formValidator enableByValidation];
[self startValidation];
self.needToUpdateUI = YES;
[self.view setNeedsLayout];
}];
@ -690,9 +682,8 @@
[[MVMCoreUISession sharedGlobal].splitViewController.rightPanel willOpenWithActionInformation:actionInformation];
}
[self.formValidator addFormParamsWithRequestParameters:requestParameters];
[self addFormParamsWithRequestParameters:requestParameters];
requestParameters.parentPageType = [self.loadObject.pageJSON stringForKey:@"parentPageType"];
[[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParameters dataForPage:additionalData delegateObject:[self delegateObject]];
}

View File

@ -17,7 +17,7 @@ open class ThreeLayerTableViewController: MFProgrammaticTableViewController {
private var footerView: UIView?
private var safeAreaView: UIView?
var useMargins: Bool = true
var bottomViewOutsideOfScrollArea: Bool = false
public var bottomViewOutsideOfScrollArea: Bool = false
private var topViewBottomConstraint: NSLayoutConstraint?
private var bottomViewTopConstraint: NSLayoutConstraint?

View File

@ -10,48 +10,48 @@ import Foundation
public extension NSLayoutConstraint {
/// Pins the views vertically in the super view, allowing the super to expand depending on the tallest view. Shorter views are aligned center.
static func pinViewsVerticalExpandableAlignCenter(_ views: [UIView]) {
/// Pins the views vertically to the top and bottom anchor, allowing the super to expand depending on the tallest view. Shorter views are aligned center.
static func pinViewsVerticalExpandableAlignCenter(_ views: [UIView], topAnchor: NSLayoutYAxisAnchor? = nil, bottomAnchor: NSLayoutYAxisAnchor? = nil, constant: CGFloat = 0) {
for view in views {
guard let superView = view.superview else {
return
}
guard let superView = view.superview else { return }
let top = topAnchor ?? superView.layoutMarginsGuide.topAnchor
let bottom = bottomAnchor ?? superView.layoutMarginsGuide.bottomAnchor
view.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true
view.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true
superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true
view.topAnchor.constraint(greaterThanOrEqualTo: top).isActive = true
bottom.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true
var constraint = view.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor)
var constraint = view.topAnchor.constraint(equalTo: top)
constraint.priority = .defaultLow
constraint.isActive = true
constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor)
constraint = bottom.constraint(equalTo: view.bottomAnchor)
constraint.priority = .defaultLow
constraint.isActive = true
}
}
/// Pins the views vertically in the super view, allowing the super to expand depending on the tallest view. Shorter views are aligned top.
static func pinViewsVerticalExpandableAlignTop(_ views: [UIView]) {
/// Pins the views vertically to the top and bottom anchor, allowing the super to expand depending on the tallest view. Shorter views are aligned top.
static func pinViewsVerticalExpandableAlignTop(_ views: [UIView], topAnchor: NSLayoutYAxisAnchor? = nil, bottomAnchor: NSLayoutYAxisAnchor? = nil, constant: CGFloat = 0) {
for view in views {
guard let superView = view.superview else {
return
}
view.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor).isActive = true
superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true
guard let superView = view.superview else { return }
let top = topAnchor ?? superView.layoutMarginsGuide.topAnchor
let bottom = bottomAnchor ?? superView.layoutMarginsGuide.bottomAnchor
view.topAnchor.constraint(equalTo: top).isActive = true
bottom.constraint(greaterThanOrEqualTo: view.bottomAnchor, constant: constant).isActive = true
let constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor)
let constraint = bottom.constraint(equalTo: view.bottomAnchor)
constraint.priority = .defaultLow
constraint.isActive = true
}
}
/// Pins a view to the left and a view to the right, flexible space in between. The super can expand depending on the taller view. Shorter views are aligned top if alignTop true, else aligned center.
static func pinViews(leftView: UIView, rightView: UIView, alignTop: Bool) {
static func pinViews(leftView: UIView, rightView: UIView, alignTop: Bool, topAnchor: NSLayoutYAxisAnchor? = nil, bottomAnchor: NSLayoutYAxisAnchor? = nil, constant: CGFloat = 0) {
guard let superView = leftView.superview else { return }
if alignTop {
pinViewsVerticalExpandableAlignTop([leftView, rightView])
pinViewsVerticalExpandableAlignTop([leftView, rightView], topAnchor: topAnchor, bottomAnchor: bottomAnchor, constant: constant)
} else {
pinViewsVerticalExpandableAlignCenter([leftView, rightView])
pinViewsVerticalExpandableAlignCenter([leftView, rightView], topAnchor: topAnchor, bottomAnchor: bottomAnchor, constant: constant)
}
leftView.leadingAnchor.constraint(equalTo: superView.layoutMarginsGuide.leadingAnchor).isActive = true
superView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightView.trailingAnchor).isActive = true

View File

@ -0,0 +1,23 @@
//
// UIStackView+Extension.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 3/16/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
extension UIStackView: MVMCoreUIMoleculeViewProtocol {
public func updateView(_ size: CGFloat) {
for view in arrangedSubviews {
(view as? MVMCoreViewProtocol)?.updateView(size)
}
}
public func reset() {
for view in arrangedSubviews {
(view as? MVMCoreUIMoleculeViewProtocol)?.reset?()
}
}
}

View File

@ -50,11 +50,14 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
// Convenience getter
+ (nullable instancetype)mainSplitViewController;
/// Initializes the splitviewcontroller with the passed in panels.
- (nullable instancetype)initWithLeftPanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)leftPanel rightPanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)rightPanel;
// Returns a split controller with the mvm styling. Also sets the appropriate handlers.
+ (nullable instancetype)setup;
+ (nullable instancetype)setup:(nullable UIViewController <MVMCoreUIPanelProtocol> *)leftPanel rightPanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)rightPanel;
// Returns a split controller with the mvm styling. Also sets the appropriate handlers. Also sets up the default load screen
+ (nullable instancetype)setupAsMainController;
+ (nullable instancetype)setupAsMainController:(nullable UIViewController <MVMCoreUIPanelProtocol> *)leftPanel rightPanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)rightPanel;
#pragma mark - Panel Functions
@ -83,9 +86,6 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
// contains speicaly logic to set the icon color
- (void)setNavigationIconColor:(nullable UIColor *)color;
///create right and left panel. if left and right panel is already created, will replace them
- (void)createPanels;
/// Updates the panels that are used.
- (void)setupPanels;
@ -123,10 +123,6 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
// Can subclass to set threshold for when the drawers are permanently extended. Default is 1000 for the left panel and 2000 for both.
- (MFNumberOfDrawers)numberOfDrawersShouldShow:(nullable NSNumber *)forWidth;
// subclass to return default global panels. kept alive after creation.
- (nullable UIViewController <MVMCoreUIPanelProtocol> *)createLeftPanelViewController;
- (nullable UIViewController <MVMCoreUIPanelProtocol> *)createRightPanelViewController;
// subclass to change image of back button
- (nullable UIImage *)imageForBackButton;

View File

@ -76,18 +76,26 @@ CGFloat const PanelAnimationDuration = 0.2;
return [MVMCoreActionUtility initializerClassCheck:[MVMCoreUISession sharedGlobal].splitViewController classToVerify:self];
}
+ (nullable instancetype)setup {
MVMCoreUISplitViewController *splitViewController = [[self alloc] init];
+ (nullable instancetype)setup:(nullable UIViewController <MVMCoreUIPanelProtocol> *)leftPanel rightPanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)rightPanel {
MVMCoreUISplitViewController *splitViewController = [[self alloc] initWithLeftPanel:leftPanel rightPanel:rightPanel];
[MVMCoreUISession sharedGlobal].splitViewController = splitViewController;
return splitViewController;
}
+ (nullable instancetype)setupAsMainController {
MVMCoreUISplitViewController *splitViewController = [self setup];
+ (nullable instancetype)setupAsMainController:(nullable UIViewController <MVMCoreUIPanelProtocol> *)leftPanel rightPanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)rightPanel {
MVMCoreUISplitViewController *splitViewController = [self setup:leftPanel rightPanel:rightPanel];
[[MVMCoreUISession sharedGlobal] setupAsStandardLoadViewDelegate:splitViewController];
return splitViewController;
}
- (nullable instancetype)initWithLeftPanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)leftPanel rightPanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)rightPanel {
if (self = [super init]) {
self.globalLeftPanel = leftPanel;
self.globalRightPanel = rightPanel;
}
return self;
}
#pragma mark - Main Subclassables
- (MFNumberOfDrawers)numberOfDrawersShouldShow:(NSNumber *)forWidth {
@ -100,14 +108,6 @@ CGFloat const PanelAnimationDuration = 0.2;
return (width > 2000 ? MFTwoDrawer : (width > 1000 ? MFOneDrawer : MFNoDrawer));
}
- (nullable UIViewController <MVMCoreUIPanelProtocol> *)createLeftPanelViewController {
return nil;
}
- (nullable UIViewController <MVMCoreUIPanelProtocol> *)createRightPanelViewController {
return nil;
}
- (nullable NSArray <UIBarButtonItem *>*)additionalLeftButtons {
return nil;
}
@ -766,13 +766,6 @@ CGFloat const PanelAnimationDuration = 0.2;
}
}
- (void)createPanels {
// Create panels
self.globalLeftPanel = [self createLeftPanelViewController];
self.globalRightPanel = [self createRightPanelViewController];
[self setupPanels];
}
- (void)setupPanels {
[self forceHideBothDrawers];
[self setupLeftPanel];
@ -869,7 +862,7 @@ CGFloat const PanelAnimationDuration = 0.2;
[NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES;
[self createPanels];
[self setupPanels];
}
- (void)viewDidLoad {

View File

@ -23,15 +23,15 @@ open class Container: View, ContainerProtocol {
}
// MARK:- ContainerProtocol
public func alignHorizontal(_ alignment: UIStackView.Alignment) {
open func alignHorizontal(_ alignment: UIStackView.Alignment) {
containerHelper.alignHorizontal(alignment)
}
public func alignVertical(_ alignment: UIStackView.Alignment) {
open func alignVertical(_ alignment: UIStackView.Alignment) {
containerHelper.alignVertical(alignment)
}
public func constrainView(_ view: UIView) {
open func constrainView(_ view: UIView) {
containerHelper.constrainView(view)
}
}

View File

@ -9,7 +9,7 @@
import Foundation
public class ContainerHelper: NSObject {
open class ContainerHelper: NSObject {
var leftConstraint: NSLayoutConstraint?
var topConstraint: NSLayoutConstraint?
var bottomConstraint: NSLayoutConstraint?
@ -28,7 +28,7 @@ public class ContainerHelper: NSObject {
var bottomLowConstraint: NSLayoutConstraint?
var rightLowConstraint: NSLayoutConstraint?
func constrainView(_ view: UIView) {
open func constrainView(_ view: UIView) {
guard let margins = view.superview?.layoutMarginsGuide else { return }
leftConstraint = view.leftAnchor.constraint(equalTo: margins.leftAnchor)
leftConstraint?.isActive = true
@ -69,7 +69,7 @@ public class ContainerHelper: NSObject {
setAccessibility(view)
}
func setAccessibility(_ view: UIView) {
open func setAccessibility(_ view: UIView) {
guard let superView = view.superview else { return }
superView.isAccessibilityElement = false
if let elements = view.accessibilityElements {
@ -79,7 +79,7 @@ public class ContainerHelper: NSObject {
}
}
func alignHorizontal(_ alignment: UIStackView.Alignment) {
open func alignHorizontal(_ alignment: UIStackView.Alignment) {
switch alignment {
case .center:
alignCenterHorizontalConstraint?.isActive = true
@ -109,7 +109,7 @@ public class ContainerHelper: NSObject {
}
}
func alignVertical(_ alignment: UIStackView.Alignment) {
open func alignVertical(_ alignment: UIStackView.Alignment) {
switch alignment {
case .center:
alignCenterVerticalConstraint?.isActive = true
@ -139,7 +139,7 @@ public class ContainerHelper: NSObject {
}
}
static func getAlignment(for string: String) -> UIStackView.Alignment? {
public static func getAlignment(for string: String) -> UIStackView.Alignment? {
switch string {
case "leading":
return .leading
@ -154,7 +154,7 @@ public class ContainerHelper: NSObject {
}
}
static func getAlignmentString(for alignment: UIStackView.Alignment?) -> String? {
public static func getAlignmentString(for alignment: UIStackView.Alignment?) -> String? {
switch alignment {
case .leading:
return "leading"
@ -169,11 +169,11 @@ public class ContainerHelper: NSObject {
}
}
func updateViewMargins(_ view: UIView, model: ContainerModelProtocol?, size: CGFloat) {
open func updateViewMargins(_ view: UIView, model: ContainerModelProtocol?, size: CGFloat) {
MFStyler.setMarginsFor(view, size: size, defaultHorizontal: model?.useHorizontalMargins ?? false, top: (model?.useVerticalMargins ?? false) ? (model?.topMarginPadding ?? 0) : 0, bottom: (model?.useVerticalMargins ?? false) ? (model?.bottomMarginPadding ?? 0) : 0)
}
func set(with model: ContainerModelProtocol, for contained: MVMCoreUIViewConstrainingProtocol?) {
open func set(with model: ContainerModelProtocol, for contained: MVMCoreUIViewConstrainingProtocol?) {
if let horizontalAlignment = model.horizontalAlignment ?? contained?.horizontalAlignment?() {
alignHorizontal(horizontalAlignment)
}
@ -182,7 +182,7 @@ public class ContainerHelper: NSObject {
}
}
func set(with JSON: [AnyHashable: Any]?, for contained: UIView) {
open func set(with JSON: [AnyHashable: Any]?, for contained: UIView) {
if let horizontalAlignmentString = JSON?.optionalStringForKey("horizontalAlignment"), let alignment = ContainerHelper.getAlignment(for: horizontalAlignmentString) ?? (contained as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() {
alignHorizontal(alignment)
} else if let alignment = (contained as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() {

View File

@ -22,7 +22,7 @@ public class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProto
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
molecule = try typeContainer.decodeMolecule(codingKey: .molecule)
molecule = try typeContainer.decodeModel(codingKey: .molecule)
try super.init(from: decoder)
}

View File

@ -0,0 +1,14 @@
//
// FormActionFieldProtocol.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 1/31/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol FormActionFieldProtocol: EnableableModelProtocol, FormItemProtocol {
func updateEnable(_ enabled: Bool)
var updateUI: (() -> Void)? { get set }
}

View File

@ -0,0 +1,22 @@
//
// FormFieldProtocol.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 1/31/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol FormFieldProtocol: FormItemProtocol {
var fieldKey: String? { get set }
var baseValue: AnyHashable? { get set }
func formFieldValue() -> AnyHashable?
}
extension FormFieldProtocol {
var baseValue: AnyHashable? {
return nil
}
}

View File

@ -0,0 +1,17 @@
//
// FormHolderProtocol.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 2/26/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
//Protocol for Validation
public protocol FormHolderProtocol: NSObjectProtocol {
var formValidator: FormValidator? { get set }
/// Should call formValidator's validate method
func validate()
}

View File

@ -0,0 +1,19 @@
//
// FormItemProtocol.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 2/25/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol FormItemProtocol {
static var defaultGroupName: String? { get }
var groupName: String? { get set }
}
extension FormItemProtocol{
public static var defaultGroupName: String? {
return "default"
}
}

View File

@ -0,0 +1,15 @@
//
// Validatable.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 2/5/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
//Protocol for Validation
public protocol FormProtocol: class {
var formRules: [FormGroupRule]? { get set }
var formValidator: FormValidator? { get set }
}

View File

@ -1,41 +0,0 @@
//
// FormValidationProtocol.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 3/26/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import Foundation
@objc public protocol FormValidationProtocol: NSObjectProtocol {
// Getter method to get the FormValidator from the delegate (Mostly from the parent View Controller)
@objc optional func formValidatorModel() -> FormValidator?
}
@objc public protocol FormValidationFormFieldProtocol: FormValidationProtocol {
// Used to check the validity of the field. For example, to enable/disable the primary button.
@objc func isValidField() -> Bool
// The Field name key value pair for sending to server
@objc func formFieldName() -> String?
// Returns the group name for validation. The class should always return a value.
@objc func formFieldGroupName() -> String?
// The Field value key value pair for sending to server
@objc func formFieldValue() -> Any?
}
@objc public protocol FormValidationEnableDisableProtocol: FormValidationProtocol {
// Returns true if the button needs to be enabled/disabled based on the validation
@objc func isValidationRequired() -> Bool
// Based on the isValidField(), the fields which needs to be enabled can call this method
@objc optional func enableField(_ enable: Bool)
// Returns the list of field keys required to enable/disable
@objc optional func requiredGroups() -> [String]?
}

View File

@ -1,28 +0,0 @@
//
// MVMCoreUIFormValidator+FormParams.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 3/21/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import Foundation
@objc public extension FormValidator {
@objc func addFormParams(requestParameters: MVMCoreRequestParameters) {
requestParameters.add(self.getFormParams())
}
@objc func getFormParams() -> [String: Any] {
var extraParam: [String: Any] = [:]
MVMCoreDispatchUtility.performSyncBlock(onMainThread: {
for molecule in self.fieldMolecules {
if let formFieldName = molecule.formFieldName(),
let formFieldValue = molecule.formFieldValue() {
extraParam[formFieldName] = formFieldValue
}
}
})
return extraParam
}
}

View File

@ -1,70 +0,0 @@
//
// MVMCoreUIFormValidator+TextFields.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 3/21/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import Foundation
@objc extension FormValidator: MFTextFieldDelegate {
public func dismissFieldInput(_ sender: Any?) {
if let delegate = delegate as? MFTextFieldDelegate {
delegate.dismissFieldInput?(sender)
}
}
public func entryIsValid(_ textfield: MFTextField?) {
MVMCoreDispatchUtility.performBlock(onMainThread: {
self.enableByValidation()
if let delegate = self.delegate as? MFTextFieldDelegate {
delegate.entryIsValid?(textfield)
}
})
}
public func entryIsInvalid(_ textfield: MFTextField?) {
MVMCoreDispatchUtility.performBlock(onMainThread: {
self.enableByValidation()
if let delegate = self.delegate as? MFTextFieldDelegate {
delegate.entryIsInvalid?(textfield)
}
})
}
}
// Temporary: Looking to either combine or separate entirely with MFTextFieldDelegate.
extension FormValidator: ObservingTextFieldDelegate {
public func dismissField(_ sender: Any?) {
if let delegate = delegate as? MFTextFieldDelegate {
delegate.dismissFieldInput?(sender)
}
}
@nonobjc public func isValid(_ textfield: MFTextField?) {
MVMCoreDispatchUtility.performBlock(onMainThread: {
self.enableByValidation()
if let delegate = self.delegate as? MFTextFieldDelegate {
delegate.entryIsValid?(textfield)
}
})
}
public func isInvalid(_ textfield: MFTextField?) {
MVMCoreDispatchUtility.performBlock(onMainThread: {
self.enableByValidation()
if let delegate = self.delegate as? MFTextFieldDelegate {
delegate.entryIsInvalid?(textfield)
}
})
}
}

View File

@ -11,75 +11,107 @@ import MVMCore
@objcMembers public class FormValidator: NSObject {
static var defaultGroupName: String = "default"
var extraValidationBlock: (() -> Bool)?
var dummyGroupName = "dummyGroupName"
weak var delegate: FormValidationProtocol?
var fieldMolecules: [FormValidationFormFieldProtocol] = []
var enableDisableMolecules: [FormValidationEnableDisableProtocol] = []
var formRules: [FormGroupRule]?
var delegate: FormHolderProtocol?
var fieldMolecules: [String: FormFieldProtocol] = [:]
var formActionMolecules: [FormActionFieldProtocol] = []
var radioButtonsModelByGroup: [String: RadioButtonSelectionHelper] = [:]
public func insertMolecule(_ molecule: FormValidationProtocol) {
if let molecule = molecule as? FormValidationFormFieldProtocol {
fieldMolecules.append(molecule)
}
if let moleculeT = molecule as? FormValidationEnableDisableProtocol,
moleculeT.isValidationRequired() {
enableDisableMolecules.append(moleculeT)
}
public init(_ formRules: [FormGroupRule]?) {
self.formRules = formRules
}
public static func enableByValidationWith(delegate: FormValidationProtocol?) {
if let delegate = delegate {
let formValidator = FormValidator.getFormValidatorFor(delegate: delegate)
formValidator?.enableByValidation()
public func insertMolecule(_ molecule: FormItemProtocol) {
if var molecule = molecule as? FormFieldProtocol,
let fieldKey = molecule.fieldKey {
if molecule.baseValue == nil {
molecule.baseValue = molecule.formFieldValue()
}
fieldMolecules[fieldKey] = molecule
}
if let molecule = molecule as? FormActionFieldProtocol {
formActionMolecules.append(molecule)
}
}
public static func getFormValidatorFor(delegate: FormValidationProtocol) -> FormValidator? {
return delegate.formValidatorModel?()
}
public static func setupValidation(molecule: FormValidationProtocol, delegate: FormValidationProtocol?) {
if let validator = delegate?.formValidatorModel?() {
public static func setupValidation(molecule: FormItemProtocol, delegate: FormHolderProtocol?) {
if let validator = delegate?.formValidator {
validator.delegate = delegate
validator.insertMolecule(molecule)
}
}
public func enableByValidation() {
for molecule in enableDisableMolecules {
var requiredGroups = molecule.requiredGroups?() ?? [dummyGroupName]
if requiredGroups.count == 0 {
requiredGroups = [dummyGroupName]
}
enableWithGroups(requiredGroups, molecule)
}
public static func getFormValidatorFor(delegate: FormHolderProtocol?) -> FormValidator? {
return delegate?.formValidator
}
public func enableWithGroups(_ requiredGroupList: [String], _ enableDisableMolecule: FormValidationEnableDisableProtocol) {
let requiredGroupSet = Set(requiredGroupList)
var valid = true
for molecule in fieldMolecules {
let groupName = molecule.formFieldGroupName() ?? dummyGroupName
if requiredGroupSet.contains(groupName) {
valid = valid && molecule.isValidField()
if valid == false {
break
}
public static func validate(delegate: FormHolderProtocol?) {
delegate?.formValidator?.validate()
}
public func validate() {
guard let formRules = formRules else {
return
}
formActionMolecules.forEach { (actionModel) in
if let groupName = actionModel.groupName,
let formRule = formRules.first(where: { $0.groupName == groupName }) {
validate(groupName, actionModel, formRule.rules)
}
}
enableDisableMolecule.enableField?(valid)
}
public func enableIgnoreGroupName(_ enableDisableMolecules: FormValidationEnableDisableProtocol) {
public func validate(_ groupName: String, _ actionModel: FormActionFieldProtocol, _ rules: [RulesProtocol]) {
var valid = true
for molecule in fieldMolecules {
valid = valid && molecule.isValidField()
if (!valid) {
for rule in rules {
valid = valid && rule.isValid(fieldMolecules)
if !valid {
break
}
}
let enableField = valid && (extraValidationBlock?() ?? true)
enableDisableMolecules.enableField?(enableField)
actionModel.updateEnable(valid)
}
public func formField(for fieldKey: String) -> FormFieldProtocol? {
return fieldMolecules[fieldKey]
}
}
// mark Form params
@objc public extension FormValidator {
@objc func addFormParams(requestParameters: MVMCoreRequestParameters) {
let formButton = getFormButton(forPageType: requestParameters.pageType)
let groupName = formButton?.groupName ?? FormValidator.defaultGroupName
let formParams = self.getFormParams(forGroup: groupName)
requestParameters.add(formParams)
}
@objc func getFormParams( forGroup groupName: String) -> [String: Any] {
var extraParam: [String: Any] = [:]
MVMCoreDispatchUtility.performSyncBlock(onMainThread: {
for (fieldKey, molecule) in self.fieldMolecules {
if let formFieldValue = molecule.formFieldValue(),
groupName == molecule.groupName {
extraParam[fieldKey] = formFieldValue
}
}
})
return extraParam
}
}
// Temporary
public extension FormValidator {
func getFormButton(forPageType pageType: String?) -> ButtonModel? {
for actionItem in formActionMolecules {
if let buttonModel = actionItem as? ButtonModel,
pageType == (buttonModel.action as? ActionOpenPageModel)?.pageType {
return buttonModel
}
}
return nil
}
}

View File

@ -0,0 +1,38 @@
//
// FormRule.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 2/24/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
open class FormGroupRule: Codable {
var groupName: String
var rules: [RulesProtocol]
init(_ groupName: String, _ rules: [RulesProtocol]) {
self.groupName = groupName
self.rules = rules
}
private enum CodingKeys: String, CodingKey {
case groupName
case rules
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
self.groupName = try typeContainer.decode(String.self, forKey: .groupName)
self.rules = try typeContainer.decodeModels(codingKey: .rules)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(groupName, forKey: .groupName)
try container.encodeModels(rules, forKey: .rules)
}
}

View File

@ -0,0 +1,20 @@
//
// RuleValueChangeModel.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 2/24/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class RuleAllValueChangedModel: RulesProtocol {
public static var identifier: String = "allValueChanged"
public var type: String = RuleAllValueChangedModel.identifier
public var fields: [String]
public func isValid(_ formField: FormFieldProtocol) -> Bool {
return formField.baseValue != formField.formFieldValue()
}
}

View File

@ -0,0 +1,49 @@
//
// RuleAnyRequiredModel.swift
// MVMCoreUI
//
// Created by Kevin Christiano on 3/13/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import UIKit
public class RuleAnyRequiredModel: RulesProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "anyRequired"
public var type: String = RuleRequiredModel.identifier
public var fields: [String]
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
public func isValid(_ formField: FormFieldProtocol) -> Bool {
guard let value = formField.formFieldValue() else { return false }
if let valueString = value as? String {
return valueString.count > 0
} else if let valueBool = value as? Bool {
return valueBool
}
return false
}
public func isValid(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool {
for formKey in fields {
guard let formField = fieldMolecules[formKey] else { continue }
if isValid(formField) {
return true
}
}
return false
}
}

View File

@ -0,0 +1,32 @@
//
// RuleAnyModel.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 2/24/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class RuleAnyValueChangedModel: RulesProtocol {
public static var identifier: String = "anyValueChanged"
public var type: String = RuleAnyValueChangedModel.identifier
public var fields: [String]
public func isValid(_ formField: FormFieldProtocol) -> Bool {
return formField.baseValue != formField.formFieldValue()
}
public func isValid(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool {
for formKey in fields {
guard let formField = fieldMolecules[formKey] else {
continue
}
if isValid(formField) {
return true
}
}
return false
}
}

View File

@ -0,0 +1,40 @@
//
// RuleEqualsModel.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 2/24/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class RuleEqualsModel: RulesProtocol {
public static var identifier: String = "equals"
public var type: String = RuleEqualsModel.identifier
public var fields: [String]
public func isValid(_ formField: FormFieldProtocol) -> Bool {
return false
}
public func isValid(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool {
var valid = true
var compareValue: AnyHashable?
for formKey in fields {
guard let formField = fieldMolecules[formKey] else {
continue
}
if compareValue == nil {
compareValue = formField.formFieldValue()
continue
}
if compareValue != formField.formFieldValue(){
valid = false
break
}
}
return valid
}
}

View File

@ -0,0 +1,23 @@
//
// RuleRegexModel.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 2/24/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class RuleRegexModel: RulesProtocol {
public static var identifier: String = "regex"
public var type: String = RuleRegexModel.identifier
public var fields: [String]
public var regex: String
public func isValid(_ formField: FormFieldProtocol) -> Bool {
if let stringToValidate = formField.formFieldValue() as? String {
return MVMCoreUIUtility.validate(stringToValidate, withRegularExpression: regex)
}
return false
}
}

View File

@ -0,0 +1,30 @@
//
// FormFieldRuleRequiredModel.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 2/24/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class RuleRequiredModel: RulesProtocol {
public static var identifier: String = "required"
public var type: String = RuleRequiredModel.identifier
public var fields: [String]
public func isValid(_ formField: FormFieldProtocol) -> Bool {
guard let value = formField.formFieldValue() else {
return false
}
var valid = true
if let valueString = value as? String {
valid = valueString.count > 0
} else if let valueBool = value as? Bool {
valid = valueBool
}
return valid
}
}

View File

@ -0,0 +1,56 @@
//
// FormBaseRulesProtocol.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 1/31/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public enum RulesCodingKey: String, CodingKey {
case ruleType
}
public protocol RulesProtocol: ModelProtocol {
var type: String { get set }
var fields: [String] { get set }
func isValid(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool
func isValid(_ formField: FormFieldProtocol) -> Bool
func setValid(_ formField: FormFieldProtocol, _ isValid: Bool)
}
public extension RulesProtocol {
var ruleType: String? {
get { return Self.identifier }
}
static var categoryCodingKey: String {
return "type"
}
static var categoryName: String {
return "\(RulesProtocol.self)"
}
func isValid(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool {
var valid = true
for formKey in fields {
guard let formField = fieldMolecules[formKey] else { continue }
let fieldValidity = isValid(formField)
setValid(formField, fieldValidity)
valid = valid && fieldValidity
}
return valid
}
func setValid(_ formField: FormFieldProtocol, _ isValid: Bool) {
guard let formFieldValid = formField as? ValidProtocol else { return }
formFieldValid.setValidity(isValid)
}
}

View File

@ -0,0 +1,15 @@
//
// ValidProtocol.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 3/2/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol ValidProtocol {
var isValid: Bool? { get set }
func setValidity(_ isValid: Bool)
var updateUI: (() -> Void)? { get set }
}

View File

@ -18,7 +18,7 @@
@import MVMCore.NSDictionary_MFConvenience;
@import MVMCore.MVMCoreJSONConstants;
@interface MFTextField() <FormValidationFormFieldProtocol>
@interface MFTextField()
@property (strong, nonatomic) UIColor *customPlaceHolderColor;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *separatorHeightConstraint;
@ -560,11 +560,7 @@
- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
[super setWithJSON:json delegateObject:delegateObject additionalData:additionalData];
if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) {
[FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol];
FormValidator *formValidator = [FormValidator getFormValidatorForDelegate:delegateObject.formValidationProtocol];
[self setWithMap:json];
self.mfTextFieldDelegate = formValidator;
[self setWithMap:json];
self.uiTextFieldDelegate = delegateObject.uiTextFieldDelegate;
[MVMCoreUICommonViewsUtility addDismissToolbar:self.textField delegate:self.uiTextFieldDelegate];
}
@ -574,24 +570,4 @@
+ (CGFloat)estimatedHeightForRow:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject {
return 76;
}
#pragma mark - FormValidationProtocol
- (BOOL)isValidField {
return self.isValid;
}
- (nullable NSString *)formFieldName {
return self.fieldKey;
}
- (nullable id)formFieldValue {
return self.text;
}
- (NSString * _Nullable)formFieldGroupName {
return self.groupName;
}
@end

View File

@ -21,7 +21,7 @@
static const CGFloat FaultTolerance = 20.f;
static const CGFloat CheckBoxHeightWidth = 18.0;
@interface MVMCoreUICheckBox () <FormValidationFormFieldProtocol, MVMCoreUIMoleculeViewProtocol>
@interface MVMCoreUICheckBox () <MVMCoreUIMoleculeViewProtocol>
@property (nonatomic, readwrite) BOOL isSelected;
@property (weak, nonatomic) UIView *checkedSquare;
@ -59,9 +59,7 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
}
- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
[FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol];
self.delegateObject = delegateObject;
self.fieldKey = [json stringForKey:KeyFieldKey];
self.isRequired = [json boolForKey:KeyRequired];
@ -109,23 +107,6 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
return checkBox;
}
#pragma mark - FormValidationProtocol
- (BOOL)isValidField {
if (self.isRequired) {
return self.isSelected;
}
return true;
}
- (nullable NSString *)formFieldName {
return self.fieldKey;
}
- (nullable id)formFieldValue {
return @(self.isSelected);
}
#pragma mark - inits
- (instancetype)init {
@ -350,7 +331,7 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
[self.checkMark updateCheckSelected:NO animated:animated];
}
[FormValidator enableByValidationWithDelegate:self.delegateObject.formValidationProtocol];
// [FormValidator enableByValidationWithDelegate:self.delegateObject.formValidationProtocol];
}
- (void)setColor:(nullable UIColor *)color forState:(UIControlState)state {

View File

@ -311,7 +311,7 @@ static CGFloat const IndicatorRectangleHeight = 4;
self.currentPage = page;
}
#pragma mark - MoleculeViewProtocol
#pragma mark - MVMCoreUIMoleculeViewProtocol
- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
NSString *colorString = [json string:KeyBackgroundColor];

View File

@ -22,7 +22,7 @@ const CGFloat SwitchKnobWidth = 20;
const CGFloat SwitchKnobHeight = 20;
const CGFloat SwitchShakeIntensity = 2;
@interface MVMCoreUISwitch () <FormValidationFormFieldProtocol, MVMCoreUIViewConstrainingProtocol>
@interface MVMCoreUISwitch () <MVMCoreUIViewConstrainingProtocol>
@property (weak, nonatomic) UIView *baseView;
@property (weak, nonatomic) UIView *knobView;
@ -147,8 +147,6 @@ const CGFloat SwitchShakeIntensity = 2;
self.json = json;
self.delegate = delegateObject;
[FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol];
NSString *color = [json string:@"onTintColor"];
if (color) {
self.onTintColor = [UIColor mfGetColorForHex:color];
@ -339,12 +337,11 @@ const CGFloat SwitchShakeIntensity = 2;
[self setState:state withoutBlockAnimated:animated];
if (self.valueChangedBlock) {
self.valueChangedBlock();
}
if (self.delegate && [self.delegate respondsToSelector:@selector(formValidationProtocol)] && [[self.delegate performSelector:@selector(formValidationProtocol)] respondsToSelector:@selector(formValidatorModel)]) {
FormValidator *formValidator = [[self.delegate performSelector:@selector(formValidationProtocol)] performSelector:@selector(formValidatorModel)];
[formValidator enableByValidation];
}
}
// if (self.delegate && [self.delegate respondsToSelector:@selector(formValidationProtocol)] && [[self.delegate performSelector:@selector(formValidationProtocol)] respondsToSelector:@selector(formValidatorModel)]) {
// FormValidator *formValidator = [[self.delegate performSelector:@selector(formValidationProtocol)] performSelector:@selector(formValidatorModel)];
// [formValidator enableByValidation];
// }
}
- (void)setState:(BOOL)state withoutBlockAnimated:(BOOL)animated {
@ -427,22 +424,4 @@ const CGFloat SwitchShakeIntensity = 2;
return [MVMCoreUIUtility hardcodedStringWithKey:@"AccToggleHint"];
}
#pragma mark FormValidationProtocol
- (NSString * _Nullable)formFieldGroupName {
return [self.json string:@"groupName"];
}
- (BOOL)isValidField {
return self.isOn && [self.json boolForKey:@"required"];
}
- (NSString *)formFieldName {
return [self.json string:KeyFieldKey];
}
- (id)formFieldValue {
return @(self.isOn);
}
@end

View File

@ -18,7 +18,7 @@
@import MVMCore.MVMCoreGetterUtility;
@import MVMCore.NSDictionary_MFConvenience;
@interface PrimaryButton() <FormValidationEnableDisableProtocol>
@interface PrimaryButton()
@property (nonatomic) BOOL smallButton;
@property (assign, nonatomic) BOOL tinyButton;
@ -671,7 +671,6 @@
self.validationRequired = [json boolForKey:@"required"];
self.requiredGroupsList = [json array:@"requiredGroups"];
[FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol];
self.primaryButtonType = PrimaryButtonTypeCustom;
NSString *style = [json string:@"style"];
@ -781,22 +780,4 @@
}
}
#pragma mark - FormValidationEnableDisableProtocol
- (BOOL)isValidationRequired {
return self.validationRequired;
}
- (NSArray<NSString *> *)requiredGroups {
return self.requiredGroupsList;
}
- (void)enableField:(BOOL)enable {
if (!self.validationRequired) {
self.enabled = YES;
} else {
self.enabled = enable;
}
}
@end

View File

@ -1,53 +0,0 @@
//
// MoleculeModelHelper.swift
// MVMCoreUI
//
// Created by Ryan on 11/12/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import Foundation
extension KeyedDecodingContainer where Key: CodingKey {
private enum TypeCodingKey: String, CodingKey {
case moleculeName
}
/// Decodes the molecule model with the given coding key based on moleculeName
public func decodeMolecule(codingKey: KeyedDecodingContainer<K>.Key) throws -> MoleculeModelProtocol {
return try decodeModel(codingKey: codingKey, typeCodingKey: TypeCodingKey.moleculeName)
}
/// Decodes the molecule model with the given coding key based on moleculeName, optional
public func decodeMoleculeIfPresent(codingKey: KeyedDecodingContainer<K>.Key) throws -> MoleculeModelProtocol? {
return try decodeModelIfPresent(codingKey: codingKey, typeCodingKey: TypeCodingKey.moleculeName)
}
/// Decodes the list of molecule models with the given coding key based on moleculeName
public func decodeMolecules(codingKey: KeyedDecodingContainer<K>.Key) throws -> [MoleculeModelProtocol] {
guard let models = try decodeModels(codingKey: codingKey, typeCodingKey: TypeCodingKey.moleculeName) as? [MoleculeModelProtocol] else {
throw ModelRegistry.Error.decoderError
}
return models
}
/// Decodes the list of molecule models with the given coding key based on moleculeName, optional
public func decodeMoleculesIfPresent(codingKey: KeyedDecodingContainer<K>.Key) throws -> [MoleculeModelProtocol]? {
return try decodeModelsIfPresent(codingKey: codingKey, typeCodingKey: TypeCodingKey.moleculeName) as? [MoleculeModelProtocol]
}
/// Decodes an array with arrays of molecules based on the identifiers, optional.
public func decodeMolecules2DIfPresent(codingKey: KeyedDecodingContainer<K>.Key) throws -> [[MoleculeModelProtocol]]? {
return try decodeModels2DIfPresent(codingKey: codingKey, typeCodingKey: TypeCodingKey.moleculeName) as? [[MoleculeModelProtocol]]
}
/// Decodes an array with arrays of models based on the identifiers.
public func decodeMolecules2D(codingKey: KeyedDecodingContainer<K>.Key) throws -> [[MoleculeModelProtocol]] {
guard let models = try decodeModels2D(codingKey: codingKey, typeCodingKey: TypeCodingKey.moleculeName) as? [[MoleculeModelProtocol]] else {
throw ModelRegistry.Error.decoderError
}
return models
}
}

View File

@ -1,16 +0,0 @@
//
// FormModelProtocol.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 10/24/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol FormModelProtocol: ModelProtocol {
var required: Bool? { get }
var fieldKey: String? { get }
var groupName: String? { get }
}

View File

@ -9,7 +9,7 @@
import Foundation
public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol {
public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol, FormProtocol {
var template: String { get }
}

View File

@ -0,0 +1,43 @@
//
// HeadersH2NoButtonsBodyText.swift
// MVMCoreUI
//
// Created by Lekshmi S on 05/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class HeadersH2NoButtonsBodyText: HeaderView {
//--------------------------------------------------
// MARK: - Outlets
//--------------------------------------------------
let headlineBody = HeadlineBody(frame: .zero)
//-------------------------------------------------------
// MARK: - View Lifecycle
//-------------------------------------------------------
open override func setupView() {
super.setupView()
headlineBody.stylePageHeader()
addMolecule(headlineBody)
}
//----------------------------------------------------
// 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? HeadersH2NoButtonsBodyTextModel else { return }
headlineBody.set(with: model.headlineBody, 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,55 @@
//
// HeadersH2NoButtonsBodyTextModel.swift
// MVMCoreUI
//
// Created by Lekshmi S on 05/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class HeadersH2NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "headerH2"
public var headlineBody: HeadlineBodyModel
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(headlineBody: HeadlineBodyModel) {
self.headlineBody = headlineBody
super.init()
}
public override func setDefaults() {
super.setDefaults()
topMarginPadding = PaddingDefaultVerticalSpacing3
bottomMarginPadding = PaddingDefaultVerticalSpacing3
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case headlineBody
}
//--------------------------------------------------
// 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)
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)
}
}

View File

@ -0,0 +1,35 @@
//
// ListOneColumnFullWidthTextBodyText.swift
// MVMCoreUI
//
// Created by Kruthika KP on 05/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class ListOneColumnFullWidthTextBodyText: TableViewCell {
//-----------------------------------------------------
// MARK: - Outlets
//-----------------------------------------------------
public var headlineBody = HeadlineBody(frame: .zero)
//-----------------------------------------------------
// MARK: - View Lifecycle
//-----------------------------------------------------
override open func setupView() {
super.setupView()
addMolecule(headlineBody)
}
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?){
super.set(with: model, delegateObject, additionalData)
guard let model = model as? ListOneColumnFullWidthTextBodyTextModel else { return }
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 90
}
}

View File

@ -0,0 +1,43 @@
//
// ListOneColumnFullWidthTextBodyTextModel.swift
// MVMCoreUI
//
// Created by Kruthika KP on 05/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class ListOneColumnFullWidthTextBodyTextModel: ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "list1CFWBdy"
public var headlineBody: HeadlineBodyModel
public init(headlineBody: HeadlineBodyModel) {
self.headlineBody = headlineBody
super.init()
}
// Defaults to set
override public func setDefaults() {
super.setDefaults()
headlineBody.style = "item"
}
private enum CodingKeys: String, CodingKey {
case moleculeName
case headlineBody
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
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(headlineBody, forKey: .headlineBody)
}
}

View File

@ -0,0 +1,68 @@
//
// ListRightVariableTotalData.swift
// MVMCoreUI
//
// Created by Kruthika KP on 02/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class ListRightVariableTotalData: TableViewCell {
//-----------------------------------------------------
// MARK: - Outlets
//-----------------------------------------------------
public var stack: Stack<StackModel>
public let leftLabel = Label.commonLabelB1(true)
public let rightLabel = Label.commonLabelB2(true)
public let bar = Line()
//-----------------------------------------------------
// MARK: - Initializers
//-----------------------------------------------------
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
stack = Stack<StackModel>.createStack(with: [(view: leftLabel, model: StackItemModel(horizontalAlignment: .leading)),
(view: bar, model: StackItemModel(horizontalAlignment: .fill)),
(view: rightLabel, model: StackItemModel(spacing: 4, horizontalAlignment: .fill))],
axis: .horizontal)
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//-----------------------------------------------------
// MARK: - View Lifecycle
//-------------------------------------------------------
override open func setupView() {
super.setupView()
bar.setStyle(.heavy)
bar.widthAnchor.constraint(equalToConstant: 20).isActive = true
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
addMolecule(stack)
stack.restack()
}
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?){
super.set(with: model, delegateObject, additionalData)
guard let model = model as? ListRightVariableTotalDataModel else { return }
leftLabel.set(with: model.leftLabel, delegateObject, additionalData)
rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
bar.set(with: model.bar, delegateObject, additionalData)
}
open override class func estimatedHeight(with molecule: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat?{
return 70
}
open override func reset() {
super.reset()
leftLabel.styleB1(true)
rightLabel.styleB2(true)
bar.setStyle(.heavy)
}
}

View File

@ -0,0 +1,57 @@
//
// ListRightVariableTotalDataModel.swift
// MVMCoreUI
//
// Created by Kruthika KP on 02/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class ListRightVariableTotalDataModel: ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "listRVLine"
public var leftLabel: LabelModel
public var rightLabel: LabelModel
public var bar: LineModel
override public func setDefaults() {
super.setDefaults()
rightLabel.hero = 0
bar.type = .heavy
if bar.backgroundColor == nil {
bar.backgroundColor = Color(uiColor: .mvmBlue)
}
}
public init (leftLabel: LabelModel, rightlabel:LabelModel, bar: LineModel){
self.leftLabel = leftLabel
self.rightLabel = rightlabel
self.bar = bar
super.init()
}
private enum CodingKeys: String, CodingKey{
case moleculeName
case leftLabel
case rightLabel
case bar
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel)
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
bar = try typeContainer.decode(LineModel.self, forKey: .bar)
try super.init(from: decoder)
}
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(leftLabel, forKey: .leftLabel)
try container.encode(rightLabel, forKey: .rightLabel)
try container.encode(bar, forKey: .bar)
}
}

View File

@ -0,0 +1,113 @@
//
// ListTwoColumnCompareChanges.swift
// MVMCoreUI
//
// Created by Lekshmi S on 24/02/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class ListTwoColumnCompareChanges: TableViewCell {
//-------------------------------------------------------
// MARK: - Outlets
//-------------------------------------------------------
let leftHeadline1 = Label.commonLabelB1(true)
let leftHeadline2 = Label.commonLabelB1(true)
let leftHeadline3 = Label.commonLabelB1(true)
let leftBody = Label.commonLabelB2(true)
let leftLink = Link()
let rightHeadline1 = Label.commonLabelB1(true)
let rightHeadline2 = Label.commonLabelB1(true)
let rightHeadline3 = Label.commonLabelB1(true)
let rightBody = Label.commonLabelB2(true)
let rightLink = Link()
let containingStack: Stack<StackModel>
//------------------------------------------------------
// MARK: - Initializers
//------------------------------------------------------
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
let stackHeadline1 = Stack<StackModel>.createStack(with: [(view: leftHeadline1, model: StackItemModel(percent: 50, verticalAlignment: .leading)),
(view: rightHeadline1, model: StackItemModel(percent: 50, verticalAlignment: .leading))],
axis: .horizontal)
let stackHeadline2 = Stack<StackModel>.createStack(with: [(view: leftHeadline2, model: StackItemModel(percent: 50, verticalAlignment: .leading)),
(view: rightHeadline2, model: StackItemModel(percent: 50, verticalAlignment: .leading))],
axis: .horizontal)
let stackHeadline3 = Stack<StackModel>.createStack(with: [(view: leftHeadline3, model: StackItemModel(percent: 50, verticalAlignment: .leading)),
(view: rightHeadline3, model: StackItemModel(percent: 50, verticalAlignment: .leading))],
axis: .horizontal)
let stackBody = Stack<StackModel>.createStack(with: [(view: leftBody, model: StackItemModel(percent: 50, verticalAlignment: .leading)),
(view: rightBody, model: StackItemModel(percent: 50, verticalAlignment: .leading))],
axis: .horizontal)
let stackLink = Stack<StackModel>.createStack(with: [(view: leftLink, model: StackItemModel(percent: 50, verticalAlignment: .leading)),
(view: rightLink, model: StackItemModel(percent: 50, verticalAlignment: .leading))],
axis: .horizontal)
containingStack = Stack<StackModel>.createStack(with: [stackHeadline1,
stackHeadline2,
stackHeadline3,
stackBody,
stackLink],
spacing: 0)
containingStack.stackModel?.molecules[1].spacing = 5
containingStack.stackModel?.molecules[2].spacing = 5
containingStack.stackModel?.molecules[4].spacing = 5
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//------------------------------------------------------
// MARK: - Properties
//------------------------------------------------------
let stackSpacing: CGFloat = 5.0
//-------------------------------------------------------
// MARK: - View Lifecycle
//-------------------------------------------------------
open override func setupView() {
super.setupView()
addMolecule(containingStack)
for molecule in containingStack.stackItems {
((molecule as? StackItem)?.view as? Stack<StackModel>)?.restack()
}
containingStack.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? ListTwoColumnCompareChangesModel else { return }
leftHeadline1.set(with: model.leftHeadline1, delegateObject, additionalData)
leftHeadline2.set(with: model.leftHeadline2, delegateObject, additionalData)
leftHeadline3.set(with: model.leftHeadline3, delegateObject, additionalData)
leftBody.set(with: model.leftBody, delegateObject, additionalData)
leftLink.set(with: model.leftLink, delegateObject, additionalData)
rightHeadline1.set(with: model.rightHeadline1, delegateObject, additionalData)
rightHeadline2.set(with: model.rightHeadline2, delegateObject, additionalData)
rightHeadline3.set(with: model.rightHeadline3, delegateObject, additionalData)
rightBody.set(with: model.rightBody, delegateObject, additionalData)
rightLink.set(with: model.rightLink, delegateObject, additionalData)
}
open override func reset() {
super.reset()
leftHeadline1.styleB1(true)
leftHeadline2.styleB1(true)
leftHeadline3.styleB1(true)
leftBody.styleB2(true)
rightHeadline1.styleB1(true)
rightHeadline2.styleB1(true)
rightHeadline3.styleB1(true)
rightBody.styleB2(true)
}
public override class func estimatedHeight(with molecule: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
return 121
}
}

View File

@ -0,0 +1,83 @@
//
// ListTwoColumnCompareChangesModel.swift
// MVMCoreUI
//
// Created by Lekshmi S on 24/02/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class ListTwoColumnCompareChangesModel: ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "list2CCmpr1"
public var leftHeadline1: LabelModel
public var leftHeadline2: LabelModel
public var leftHeadline3: LabelModel
public var leftBody: LabelModel
public var leftLink: LinkModel
public var rightHeadline1: LabelModel
public var rightHeadline2: LabelModel
public var rightHeadline3: LabelModel
public var rightBody: LabelModel
public var rightLink: LinkModel
public init(leftHeadline1: LabelModel, leftHeadline2: LabelModel, leftHeadline3: LabelModel, leftBody: LabelModel, leftLink: LinkModel, rightHeadline1: LabelModel, rightHeadline2: LabelModel, rightHeadline3: LabelModel, rightBody: LabelModel, rightLink: LinkModel) {
self.leftHeadline1 = leftHeadline1
self.leftHeadline2 = leftHeadline2
self.leftHeadline3 = leftHeadline3
self.leftBody = leftBody
self.leftLink = leftLink
self.rightHeadline1 = rightHeadline1
self.rightHeadline2 = rightHeadline2
self.rightHeadline3 = rightHeadline3
self.rightBody = rightBody
self.rightLink = rightLink
super.init()
}
private enum CodingKeys: String, CodingKey {
case moleculeName
case leftHeadline1
case leftHeadline2
case leftHeadline3
case leftBody
case leftLink
case rightHeadline1
case rightHeadline2
case rightHeadline3
case rightBody
case rightLink
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
leftHeadline1 = try typeContainer.decode(LabelModel.self, forKey: .leftHeadline1)
leftHeadline2 = try typeContainer.decode(LabelModel.self, forKey: .leftHeadline2)
leftHeadline3 = try typeContainer.decode(LabelModel.self, forKey: .leftHeadline3)
leftBody = try typeContainer.decode(LabelModel.self, forKey: .leftBody)
leftLink = try typeContainer.decode(LinkModel.self, forKey: .leftLink)
rightHeadline1 = try typeContainer.decode(LabelModel.self, forKey: .rightHeadline1)
rightHeadline2 = try typeContainer.decode(LabelModel.self, forKey: .rightHeadline2)
rightHeadline3 = try typeContainer.decode(LabelModel.self, forKey: .rightHeadline3)
rightBody = try typeContainer.decode(LabelModel.self, forKey: .rightBody)
rightLink = try typeContainer.decode(LinkModel.self, forKey: .rightLink)
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(leftHeadline1, forKey: .leftHeadline1)
try container.encode(leftHeadline2, forKey: .leftHeadline2)
try container.encode(leftHeadline3, forKey: .leftHeadline3)
try container.encode(leftBody, forKey: .leftBody)
try container.encode(leftLink, forKey: .leftLink)
try container.encode(rightHeadline1, forKey: .rightHeadline1)
try container.encode(rightHeadline2, forKey: .rightHeadline2)
try container.encode(rightHeadline3, forKey: .rightHeadline3)
try container.encode(rightBody, forKey: .rightBody)
try container.encode(rightLink, forKey: .rightLink)
}
}

View File

@ -0,0 +1,94 @@
//
// ListTwoColumnPriceDescription.swift
// MVMCoreUI
//
// Created by Kruthika KP on 24/02/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class ListTwoColumnPriceDescription: TableViewCell {
//-----------------------------------------------------
// MARK: - Outlets
//-------------------------------------------------------
public let leftHeadline = Label.commonLabelB1(true)
public let leftBody = Label.commonLabelB2(true)
public let rightLabel = Label.commonLabelB2(true)
public let rightSubLabel = Label.commonLabelB2(true)
public let view = MVMCoreUICommonViewsUtility.commonView()
public let leftVerticalStack: UIStackView
public let rightVerticalStack: UIStackView
//------------------------------------------------------
// MARK: - Initializers
//------------------------------------------------------
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
leftVerticalStack = UIStackView(arrangedSubviews: [leftHeadline, leftBody])
leftVerticalStack.axis = .vertical
leftVerticalStack.alignment = .leading
rightVerticalStack = UIStackView(arrangedSubviews: [rightLabel, rightSubLabel])
rightVerticalStack.axis = .vertical
rightVerticalStack.alignment = .trailing
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//-----------------------------------------------------
// MARK: - View Lifecycle
//-------------------------------------------------------
open override func updateView(_ size: CGFloat) {
super.updateView(size)
leftVerticalStack.updateView(size)
rightVerticalStack.updateView(size)
}
override open func setupView() {
super.setupView()
contentView.addSubview(view)
containerHelper.constrainView(view)
leftVerticalStack.translatesAutoresizingMaskIntoConstraints = false
rightVerticalStack.translatesAutoresizingMaskIntoConstraints = false
rightLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
rightSubLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
view.addSubview(leftVerticalStack)
view.addSubview(rightVerticalStack)
NSLayoutConstraint.pinViews(leftView: leftVerticalStack, rightView: rightVerticalStack, alignTop: true)
leftHeadline.numberOfLines = 1
rightLabel.numberOfLines = 1
rightSubLabel.numberOfLines = 1
}
//----------------------------------------------------
// 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? ListTwoColumnPriceDescriptionModel else { return }
leftHeadline.set(with: model.leftHeadline, delegateObject, additionalData)
leftBody.set(with: model.leftBody, delegateObject, additionalData)
rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
rightSubLabel.set(with: model.rightSubLabel, delegateObject, additionalData)
}
open override class func estimatedHeight(with molecule: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 80
}
override open func reset() {
super.reset()
leftVerticalStack.reset()
rightVerticalStack.reset()
leftHeadline.styleB1(true)
leftBody.styleB2(true)
rightLabel.styleB2(true)
rightSubLabel.styleB2(true)
}
}

View File

@ -0,0 +1,66 @@
//
// ListTwoColumnPriceDescriptionModel.swift
// MVMCoreUI
//
// Created by Kruthika KP on 26/02/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class ListTwoColumnPriceDescriptionModel: ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "list2CTxtPrc1"
public var leftHeadline: LabelModel
public var leftBody: LabelModel
public var rightLabel: LabelModel
public var rightSubLabel: LabelModel
override public func setDefaults() {
super.setDefaults()
rightLabel.hero = 0
if rightSubLabel.textColor == nil {
rightSubLabel.textColor = Color(uiColor: .mvmCoolGray6)
}
if rightSubLabel.attributes == nil {
rightSubLabel.attributes = [LabelAttributeStrikeThroughModel(0, rightSubLabel.text.count)]
}
}
public init(leftHeadline: LabelModel,leftBody: LabelModel, rightLabel: LabelModel, rightSubLabel: LabelModel) {
self.leftHeadline = leftHeadline
self.leftBody = leftBody
self.rightLabel = rightLabel
self.rightSubLabel = rightSubLabel
super.init()
}
private enum CodingKeys: String, CodingKey {
case moleculeName
case leftHeadline
case leftBody
case rightLabel
case rightSubLabel
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
leftHeadline = try typeContainer.decode(LabelModel.self, forKey: .leftHeadline)
leftBody = try typeContainer.decode(LabelModel.self, forKey: .leftBody)
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
rightSubLabel = try typeContainer.decode(LabelModel.self, forKey: .rightSubLabel)
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(leftHeadline, forKey: .leftHeadline)
try container.encode(leftBody, forKey: .leftBody)
try container.encode(rightLabel, forKey: .rightLabel)
try container.encode(rightSubLabel, forKey: .rightSubLabel)
}
}

View File

@ -0,0 +1,54 @@
//
// ListTwoColumnPriceDetails.swift
// MVMCoreUI
//
// Created by Lekshmi S on 19/02/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import UIKit
@objcMembers open class ListTwoColumnPriceDetails: TableViewCell {
let leftLabel = Label.commonLabelB2(true)
let rightLabel = Label.commonLabelB2(true)
let view = MVMCoreUICommonViewsUtility.commonView()
// MARK: - MFViewProtocol
open override func setupView() {
super.setupView()
view.addSubview(leftLabel)
view.addSubview(rightLabel)
NSLayoutConstraint.pinViews(leftView: leftLabel, rightView: rightLabel, alignTop: true)
contentView.addSubview(view)
containerHelper.constrainView(view)
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
rightLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
}
open override func updateView(_ size: CGFloat) {
super.updateView(size)
leftLabel.updateView(size)
rightLabel.updateView(size)
}
// MARK: - MVMCoreUIMoleculeViewProtocol
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? ListTwoColumnPriceDetailsModel else { return }
leftLabel.set(with: model.leftLabel, delegateObject, additionalData)
rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
}
open override func reset() {
super.reset()
leftLabel.reset()
rightLabel.reset()
leftLabel.styleB2(true)
rightLabel.styleB2(true)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
return 15
}
}

View File

@ -0,0 +1,54 @@
//
// ListTwoColumnPriceDetailsModel.swift
// MVMCoreUI
//
// Created by Lekshmi S on 19/02/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class ListTwoColumnPriceDetailsModel: ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "list2CTxtPrc2"
public var leftLabel: LabelModel
public var rightLabel: LabelModel
public init(leftLabel: LabelModel, rightLabel:LabelModel) {
self.leftLabel = leftLabel
self.rightLabel = rightLabel
super.init()
}
/// Defaults to set
override public func setDefaults() {
super.setDefaults()
style = "none"
if leftLabel.textColor == nil {
leftLabel.textColor = Color(uiColor: .mvmCoolGray6)
}
if rightLabel.textColor == nil {
rightLabel.textColor = Color(uiColor: .mvmCoolGray6)
}
}
private enum CodingKeys: String, CodingKey {
case moleculeName
case leftLabel
case rightLabel
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel)
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
try super.init(from: decoder)
}
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(leftLabel, forKey: .leftLabel)
try container.encode(rightLabel, forKey: .rightLabel)
}
}

View File

@ -0,0 +1,73 @@
//
// ListProgressBarData.swift
// MVMCoreUI
//
// Created by Kruthika KP on 18/02/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import UIKit
@objcMembers open class ListProgressBarData: TableViewCell {
//-----------------------------------------------------
// MARK: - Outlets
//-----------------------------------------------------
let progressBar = MultiProgress(frame: .zero)
let leftLabel = Label.createLabelBoldBodySmall(true)
let rightLabel = Label.createLabelBoldBodySmall(true)
let view = MVMCoreUICommonViewsUtility.commonView()
//-----------------------------------------------------
// MARK: - MFViewProtocol
//-----------------------------------------------------
override open func setupView() {
super.setupView()
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
view.addSubview(progressBar)
view.addSubview(leftLabel)
view.addSubview(rightLabel)
contentView.addSubview(view)
containerHelper.constrainView(view)
NSLayoutConstraint.pinViews(leftView: leftLabel, rightView: rightLabel, alignTop: true, bottomAnchor: progressBar.topAnchor, constant: 8)
progressBar.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
progressBar.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
view.bottomAnchor.constraint(equalTo: progressBar.bottomAnchor).isActive = true
}
public override func updateView(_ size: CGFloat) {
super.updateView(size)
progressBar.updateView(size)
leftLabel.updateView(size)
rightLabel.updateView(size)
}
//-----------------------------------------------------
// MARK: - ModelMoleculeViewProtocol
//-----------------------------------------------------
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? ListProgressBarDataModel else { return}
progressBar.set(with: model.progressBar, delegateObject, additionalData)
leftLabel.set(with: model.leftLabel, delegateObject, additionalData)
rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 90
}
//-----------------------------------------------------
// MARK: - MVMCoreUIMoleculeViewProtocol
//-----------------------------------------------------
override open func reset() {
super.reset()
progressBar.reset()
leftLabel.reset()
rightLabel.reset()
leftLabel.styleBoldBodySmall(true)
rightLabel.styleBoldBodySmall(true)
}
}

View File

@ -0,0 +1,47 @@
//
// ListProgressBarDataModel.swift
// MVMCoreUI
//
// Created by Kruthika KP on 18/02/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class ListProgressBarDataModel : ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "listPrgBarData"
public var progressBar : MultiProgressBarModel
public var leftLabel: LabelModel
public var rightLabel: LabelModel
public init (progressBar: MultiProgressBarModel, leftLabel: LabelModel, rightLabel: LabelModel){
self.progressBar = progressBar
self.leftLabel = leftLabel
self.rightLabel = rightLabel
super.init()
}
private enum CodingKeys: String, CodingKey{
case moleculeName
case progressBar
case leftLabel
case rightLabel
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
progressBar = try typeContainer.decode(MultiProgressBarModel.self, forKey: .progressBar)
leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel)
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
try super.init(from: decoder)
}
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(progressBar, forKey: .progressBar)
try container.encode(leftLabel, forKey: .leftLabel)
try container.encode(rightLabel, forKey: .rightLabel)
}
}

View File

@ -38,7 +38,7 @@ import Foundation
stack.restack()
}
// MARK: - MVMCoreUIMoleculeViewProtocol
// MARK: - ModelMoleculeViewProtocol
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? ListFourColumnDataUsageDividerModel else { return }
@ -48,6 +48,10 @@ import Foundation
label4.set(with: model.label4, delegateObject, additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
return 121
}
// MARK: - MVMCoreUIMoleculeViewProtocol
open override func reset() {
super.reset()
@ -56,8 +60,4 @@ import Foundation
label3.styleBoldBodySmall(true)
label4.styleBoldBodySmall(true)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
return 121
}
}

View File

@ -0,0 +1,56 @@
//
// ListOneColumnFullWidthTextDividerSubsection.swift
// MVMCoreUI
//
// Created by Dhamodaram Nandi on 09/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class ListOneColumnFullWidthTextDividerSubsection: TableViewCell {
//-----------------------------------------------------
// MARK: - Outlets
//-----------------------------------------------------
public var stack: Stack<StackModel>
public let headline = Label.commonLabelB1(true)
public let body = Label.commonLabelB2(true)
// MARK: - Initializers
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
stack = Stack<StackModel>.createStack(with: [(view: headline, model: StackItemModel(horizontalAlignment: .leading)),
(view: body, model: StackItemModel(spacing: 0, horizontalAlignment: .leading))],
axis: .vertical)
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//-----------------------------------------------------
// MARK: - View Lifecycle
//-----------------------------------------------------
override open func setupView() {
super.setupView()
addMolecule(stack)
stack.restack()
}
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? ListOneColumnFullWidthTextDividerSubsectionModel else { return }
headline.set(with: model.headline, delegateObject, additionalData)
body.set(with: model.body, delegateObject, additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 90
}
open override func reset() {
super.reset()
headline.styleB1(true)
body.styleB2(true)
}
}

View File

@ -0,0 +1,48 @@
//
// ListOneColumnFullWidthTextDividerSubsectionModel.swift
// MVMCoreUI
//
// Created by Dhamodaram Nandi on 09/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class ListOneColumnFullWidthTextDividerSubsectionModel: ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "list1CTxtDiv3"
public var headline: LabelModel
public var body: LabelModel
public init(headline: LabelModel, body: LabelModel) {
self.headline = headline
self.body = body
super.init()
}
/// Defaults to set
override public func setDefaults() {
super.setDefaults()
style = "tallDivider"
}
private enum CodingKeys: String, CodingKey {
case moleculeName
case headline
case body
}
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)
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)
}
}

View File

@ -35,7 +35,7 @@ import Foundation
stack.restack()
}
// MARK: - MVMCoreUIMoleculeViewProtocol
// MARK: - ModelMoleculeViewProtocol
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? ListThreeColumnPlanDataDividerModel else { return }

View File

@ -0,0 +1,63 @@
//
// Header.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 3/6/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
open class HeaderView: Container {
public let line = Line()
/// Convenience for doing some default setting
open var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)?
var headerModel: HeaderModel? {
get { return model as? HeaderModel }
}
/// Convenience function to add a molecule to the view.
open func addMolecule(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) {
addSubview(molecule)
containerHelper.constrainView(molecule)
self.molecule = molecule
}
// MARK: - MVMCoreViewProtocol
open override func updateView(_ size: CGFloat) {
super.updateView(size)
line.updateView(size)
molecule?.updateView(size)
}
public override func setupView() {
super.setupView()
line.setStyle(.heavy)
addSubview(line)
NSLayoutConstraint.pinViewBottom(toSuperview: line, useMargins: false, constant: 0).isActive = true
NSLayoutConstraint.pinViewLeft(toSuperview: line, useMargins: true, constant: 0).isActive = true
NSLayoutConstraint.pinViewRight(toSuperview: line, useMargins: true, constant: 0).isActive = true
}
// MARK: - MVMCoreUIMoleculeViewProtocol
open override func reset() {
super.reset()
line.setStyle(.heavy)
molecule?.reset?()
}
// MARK: - ModelMoleculeViewProtocol
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let headerModel = headerModel else { return }
if let lineModel = headerModel.line {
line.set(with: lineModel, delegateObject, additionalData)
}
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return PaddingDefaultVerticalSpacing + PaddingDefaultVerticalSpacing
}
}

View File

@ -14,4 +14,9 @@ public struct ImageHeadlineBodyModel: MoleculeModelProtocol {
public var backgroundColor: Color?
public var image: ImageViewModel
public var headlineBody: HeadlineBodyModel
public init(image: ImageViewModel, headlineBody: HeadlineBodyModel) {
self.image = image
self.headlineBody = headlineBody
}
}

View File

@ -109,7 +109,9 @@ import UIKit
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? TwoButtonViewModel else { return }
if let secondaryModel = model.secondaryButton {
showSecondaryButton()
secondaryButton.set(with: secondaryModel, delegateObject, additionalData)

View File

@ -29,10 +29,7 @@ class AccordionListItemModel: MoleculeListItemModel {
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
guard let molecules = try typeContainer.decodeMolecules(codingKey: .molecules) as? [ListItemModelProtocol & MoleculeModelProtocol] else {
throw DecodingError.typeMismatch([ListItemModelProtocol & MoleculeModelProtocol].self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Casting failed"))
}
self.molecules = molecules
molecules = try typeContainer.decodeModels(codingKey: .molecules)
if let hideLine = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideLineWhenExpanded) {
hideLineWhenExpanded = hideLine
}

View File

@ -30,7 +30,8 @@ import UIKit
let self = self,
let index = self.dropDown.pickerData.firstIndex(of: newValue),
let dropListItemJSON = (self.listItemModel as? DropDownListItemModel).toJSON(),
let json2d = dropListItemJSON.optionalArrayForKey("molecules") as? [[[AnyHashable: Any]]]
let json2d = dropListItemJSON.optionalArrayForKey("molecules") as? [[[AnyHashable: Any]]],
!json2d.isEmpty && !(json2d.first?.isEmpty ?? false)
else { return }
if self.previousIndex != NSNotFound {

View File

@ -51,7 +51,7 @@ import Foundation
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
molecules = try typeContainer.decodeMolecules2D(codingKey: .molecules) as? [[ListItemModelProtocol & MoleculeModelProtocol]] ?? [[]]
molecules = try typeContainer.decodeModels2DIfPresent(codingKey: .molecules) ?? [[]]
dropDown = try typeContainer.decode(ItemDropdownEntryFieldModel.self, forKey: .dropDown)
try super.init(from: decoder)
}

View File

@ -65,7 +65,7 @@ import Foundation
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType)
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
hideArrow = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideArrow)
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
style = try typeContainer.decodeIfPresent(String.self, forKey: .style)

View File

@ -27,7 +27,7 @@ import MVMCore
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
molecule = try typeContainer.decodeMolecule(codingKey: .molecule)
molecule = try typeContainer.decodeModel(codingKey: .molecule)
try super.init(from: decoder)
}

View File

@ -14,18 +14,18 @@ import UIKit
// MARK: - MVMCoreUIMoleculeViewProtocol
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? MoleculeListItemModel else { return }
if molecule != nil {
(molecule as? ModelMoleculeViewProtocol)?.set(with: model.molecule, delegateObject, additionalData)
} else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(model.molecule, delegateObject, false) {
addMolecule(moleculeView)
guard let castModel = model as? MoleculeListItemModel else {
super.set(with: model, delegateObject, additionalData)
return
}
containerHelper.set(with: model, for: molecule as? MVMCoreUIViewConstrainingProtocol)
if molecule != nil {
(molecule as? ModelMoleculeViewProtocol)?.set(with: castModel.molecule, delegateObject, additionalData)
} else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(castModel.molecule, delegateObject, false) {
addMolecule(moleculeView)
}
super.set(with: model, delegateObject, additionalData)
}
public override class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {

View File

@ -37,7 +37,7 @@ public class TabsListItemModel: ListItemModel, MoleculeModelProtocol {
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
tabs = try typeContainer.decode(TabsModel.self, forKey: .tabs)
molecules = try typeContainer.decodeMolecules2D(codingKey: .molecules) as! [[ListItemModelProtocol & MoleculeModelProtocol]]
molecules = try typeContainer.decodeModels2D(codingKey: .molecules)
try super.init(from: decoder)
}

View File

@ -152,7 +152,7 @@ import UIKit
styleDefault()
spaceAboveMolecule = 6.0
spaceBelowMolecule = 6.0
(middleView as? MoleculeViewProtocol)?.reset?()
(middleView as? MVMCoreUIMoleculeViewProtocol)?.reset?()
}
func styleDefault() {

View File

@ -34,7 +34,7 @@ public class CornerLabelsModel: MoleculeModelProtocol {
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
molecule = try typeContainer.decodeMoleculeIfPresent(codingKey: .molecule)
molecule = try typeContainer.decodeModelIfPresent(codingKey: .molecule)
topLeftLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .topLeftLabel)
topRightLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .topRightLabel)
bottomLeftLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .bottomLeftLabel)

View File

@ -24,7 +24,7 @@ import Foundation
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
molecule = try typeContainer.decodeMolecule(codingKey: .molecule)
molecule = try typeContainer.decodeModel(codingKey: .molecule)
try super.init(from: decoder)
}

View File

@ -8,7 +8,7 @@
import UIKit
@objcMembers public class RadioButtonLabel: ViewConstrainingView {
@objcMembers public class RadioButtonLabel: View {
public let radioButton = RadioButton()
var delegateObject: MVMCoreUIDelegateObject?
@ -65,26 +65,12 @@ import UIKit
let rightView = ViewConstrainingView(constrainingView: label)
return rightView
}
}
// MARK: - MVMCoreUIMoleculeViewProtocol
extension RadioButtonLabel {
@objc open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
self.delegateObject = delegateObject
radioButton.setWithJSON(json?.optionalDictionaryForKey("radioButton"), delegateObject: delegateObject, additionalData: additionalData)
label.setWithJSON(json?.optionalDictionaryForKey(KeyLabel),
delegateObject: delegateObject,
additionalData: additionalData)
}
public override func reset() {
super.reset()
radioButton.reset()
label.reset()
}
public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
return 45
}
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let radioButtonLabelModel = model as? RadioButtonLabelModel else { return }
radioButton.set(with: radioButtonLabelModel.radioButton, delegateObject, additionalData)
label.set(with: radioButtonLabelModel.label, delegateObject, additionalData)
}
}

View File

@ -0,0 +1,17 @@
//
// RadioButtonLabelModel.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 3/3/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers public class RadioButtonLabelModel: MoleculeModelProtocol {
public static var identifier: String = "radioButtonLabel"
public var backgroundColor: Color?
public var radioButton: RadioButtonModel
public var label: LabelModel
}

Some files were not shown because too many files have changed in this diff Show More