Merge branch 'develop' into feature/Headers_H2_Buttons
# Conflicts: # MVMCoreUI/Atomic/MoleculeObjectMapping.swift
This commit is contained in:
commit
91a5b3d36c
@ -61,7 +61,6 @@
|
|||||||
01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */; };
|
01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */; };
|
||||||
01EB368F23609801006832FA /* LabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368823609801006832FA /* LabelModel.swift */; };
|
01EB368F23609801006832FA /* LabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368823609801006832FA /* LabelModel.swift */; };
|
||||||
01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368923609801006832FA /* MoleculeListItemModel.swift */; };
|
01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368923609801006832FA /* MoleculeListItemModel.swift */; };
|
||||||
01EB369223609801006832FA /* MoleculeStackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368B23609801006832FA /* MoleculeStackModel.swift */; };
|
|
||||||
01EB369323609801006832FA /* HeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368C23609801006832FA /* HeaderModel.swift */; };
|
01EB369323609801006832FA /* HeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368C23609801006832FA /* HeaderModel.swift */; };
|
||||||
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368D23609801006832FA /* HeadlineBodyModel.swift */; };
|
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368D23609801006832FA /* HeadlineBodyModel.swift */; };
|
||||||
01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A03123A4498200D954D8 /* CaretLinkModel.swift */; };
|
01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A03123A4498200D954D8 /* CaretLinkModel.swift */; };
|
||||||
@ -95,6 +94,7 @@
|
|||||||
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; };
|
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; };
|
||||||
0A7ECC5D243CE85300C828E8 /* DoughnutChartItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7ECC5C243CE85300C828E8 /* DoughnutChartItemModel.swift */; };
|
0A7ECC5D243CE85300C828E8 /* DoughnutChartItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7ECC5C243CE85300C828E8 /* DoughnutChartItemModel.swift */; };
|
||||||
0A7ECC5F243CEB1200C828E8 /* ColorViewWithLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7ECC5E243CEB1200C828E8 /* ColorViewWithLabel.swift */; };
|
0A7ECC5F243CEB1200C828E8 /* ColorViewWithLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7ECC5E243CEB1200C828E8 /* ColorViewWithLabel.swift */; };
|
||||||
|
0A7ECC702441001C00C828E8 /* UIToolbar+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7ECC6F2441001C00C828E8 /* UIToolbar+Extension.swift */; };
|
||||||
0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85A23D8A52800B2AAD1 /* EntryFieldModel.swift */; };
|
0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85A23D8A52800B2AAD1 /* EntryFieldModel.swift */; };
|
||||||
0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */; };
|
0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */; };
|
||||||
0A7EF85F23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */; };
|
0A7EF85F23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */; };
|
||||||
@ -103,6 +103,8 @@
|
|||||||
0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */; };
|
0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */; };
|
||||||
0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */; };
|
0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */; };
|
||||||
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B392398524F0067DD0F /* Toggle.swift */; };
|
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B392398524F0067DD0F /* Toggle.swift */; };
|
||||||
|
0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */; };
|
||||||
|
0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */; };
|
||||||
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; };
|
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; };
|
||||||
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; };
|
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; };
|
||||||
0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; };
|
0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; };
|
||||||
@ -139,8 +141,12 @@
|
|||||||
8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */; };
|
8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */; };
|
||||||
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D4687E1242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift */; };
|
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D4687E1242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift */; };
|
||||||
8D4687E4242E2DF300802879 /* ListFourColumnDataUsageListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D4687E3242E2DF300802879 /* ListFourColumnDataUsageListItem.swift */; };
|
8D4687E4242E2DF300802879 /* ListFourColumnDataUsageListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D4687E3242E2DF300802879 /* ListFourColumnDataUsageListItem.swift */; };
|
||||||
|
8D8067D12444472F00203BE8 /* ListRightVariablePriceChangeAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D8067D02444472F00203BE8 /* ListRightVariablePriceChangeAllTextAndLinksModel.swift */; };
|
||||||
|
8D8067D32444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D8067D22444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift */; };
|
||||||
8DD1E36E243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DD1E36D243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift */; };
|
8DD1E36E243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DD1E36D243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift */; };
|
||||||
8DD1E370243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DD1E36F243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift */; };
|
8DD1E370243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DD1E36F243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift */; };
|
||||||
|
8DDD6C1D244D90B8006A2232 /* ListThreeColumnDataUsage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DDD6C1C244D90B8006A2232 /* ListThreeColumnDataUsage.swift */; };
|
||||||
|
8DDD6C1F244D90E1006A2232 /* ListThreeColumnDataUsageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DDD6C1E244D90E1006A2232 /* ListThreeColumnDataUsageModel.swift */; };
|
||||||
8DEFA95C243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DEFA95B243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift */; };
|
8DEFA95C243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DEFA95B243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift */; };
|
||||||
8DEFA95E243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DEFA95D243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift */; };
|
8DEFA95E243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DEFA95D243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift */; };
|
||||||
942C372E241149170066E45E /* NHaasGroteskDSStd-75Bd.otf in Resources */ = {isa = PBXBuildFile; fileRef = 942C372C241149170066E45E /* NHaasGroteskDSStd-75Bd.otf */; };
|
942C372E241149170066E45E /* NHaasGroteskDSStd-75Bd.otf in Resources */ = {isa = PBXBuildFile; fileRef = 942C372C241149170066E45E /* NHaasGroteskDSStd-75Bd.otf */; };
|
||||||
@ -148,8 +154,8 @@
|
|||||||
942C378C2412F4FA0066E45E /* ModalMoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */; };
|
942C378C2412F4FA0066E45E /* ModalMoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */; };
|
||||||
942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 942C378D2412F5B60066E45E /* ModalMoleculeStackTemplate.swift */; };
|
942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 942C378D2412F5B60066E45E /* ModalMoleculeStackTemplate.swift */; };
|
||||||
9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; };
|
9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; };
|
||||||
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; };
|
943784F5236B77BB006A1E82 /* Wheel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* Wheel.swift */; };
|
||||||
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; };
|
943784F6236B77BB006A1E82 /* WheelAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* WheelAnimationHandler.swift */; };
|
||||||
943820842432382400B43AF3 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943820832432382400B43AF3 /* WebView.swift */; };
|
943820842432382400B43AF3 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943820832432382400B43AF3 /* WebView.swift */; };
|
||||||
94382086243238D100B43AF3 /* WebViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94382085243238D100B43AF3 /* WebViewModel.swift */; };
|
94382086243238D100B43AF3 /* WebViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94382085243238D100B43AF3 /* WebViewModel.swift */; };
|
||||||
9445890C2385BCE300DE9FD4 /* ProgressBarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */; };
|
9445890C2385BCE300DE9FD4 /* ProgressBarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */; };
|
||||||
@ -182,6 +188,7 @@
|
|||||||
94CA227F24058534002D6750 /* VerizonNHGeTX-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227B24058533002D6750 /* VerizonNHGeTX-Regular.otf */; };
|
94CA227F24058534002D6750 /* VerizonNHGeTX-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227B24058533002D6750 /* VerizonNHGeTX-Regular.otf */; };
|
||||||
94F217B623E0BF6100A47C06 /* PrimaryButtonView.h in Headers */ = {isa = PBXBuildFile; fileRef = 94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
94F217B623E0BF6100A47C06 /* PrimaryButtonView.h in Headers */ = {isa = PBXBuildFile; fileRef = 94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
94F217B723E0BF6100A47C06 /* PrimaryButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */; };
|
94F217B723E0BF6100A47C06 /* PrimaryButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */; };
|
||||||
|
94F6516D2437954100631BF9 /* Tabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94F6516C2437954100631BF9 /* Tabs.swift */; };
|
||||||
94FB966223D797DA003D482B /* MFTextButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 94FB966023D797DA003D482B /* MFTextButton.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
94FB966223D797DA003D482B /* MFTextButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 94FB966023D797DA003D482B /* MFTextButton.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
94FB966323D797DA003D482B /* MFTextButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 94FB966123D797DA003D482B /* MFTextButton.m */; };
|
94FB966323D797DA003D482B /* MFTextButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 94FB966123D797DA003D482B /* MFTextButton.m */; };
|
||||||
AA104B1A24474A66004D2810 /* HeadersH2Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */; };
|
AA104B1A24474A66004D2810 /* HeadersH2Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */; };
|
||||||
@ -190,16 +197,30 @@
|
|||||||
AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */; };
|
AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */; };
|
||||||
AA1EC59724373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA1EC59624373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift */; };
|
AA1EC59724373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA1EC59624373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift */; };
|
||||||
AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA1EC59824373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift */; };
|
AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA1EC59824373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift */; };
|
||||||
|
AA2AD116244EE46800BBFFE3 /* ListDeviceComplexLinkMedium.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA2AD115244EE46800BBFFE3 /* ListDeviceComplexLinkMedium.swift */; };
|
||||||
|
AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA2AD117244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift */; };
|
||||||
AA56A20F243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA56A20E243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift */; };
|
AA56A20F243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA56A20E243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift */; };
|
||||||
AA56A211243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA56A210243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift */; };
|
AA56A211243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA56A210243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift */; };
|
||||||
|
AA617AB02453010A00910B8F /* ListDeviceComplexLinkSmall.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA617AAF2453010A00910B8F /* ListDeviceComplexLinkSmall.swift */; };
|
||||||
|
AA617AB22453012400910B8F /* ListDeviceComplexLinkSmallModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA617AB12453012400910B8F /* ListDeviceComplexLinkSmallModel.swift */; };
|
||||||
|
AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA69AAF52445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift */; };
|
||||||
|
AA69AAF82445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA69AAF72445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift */; };
|
||||||
|
AA85236C244435A20059CC1E /* RadioSwatchCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */; };
|
||||||
AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */; };
|
AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */; };
|
||||||
AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */; };
|
AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */; };
|
||||||
|
AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; };
|
||||||
|
AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatch.swift */; };
|
||||||
|
AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; };
|
||||||
|
BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */; };
|
||||||
|
BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */; };
|
||||||
BB2C968F24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */; };
|
BB2C968F24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */; };
|
||||||
BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */; };
|
BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */; };
|
||||||
BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */; };
|
BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */; };
|
||||||
BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */; };
|
BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */; };
|
||||||
BB54C5202434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */; };
|
BB54C5202434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */; };
|
||||||
BB54C5212434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB54C51F2434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift */; };
|
BB54C5212434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB54C51F2434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift */; };
|
||||||
|
BB55B51D244482C1002001AD /* ListRightVariablePriceChangeBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB55B51C244482C0002001AD /* ListRightVariablePriceChangeBodyText.swift */; };
|
||||||
|
BB55B51F244482D2002001AD /* ListRightVariablePriceChangeBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB55B51E244482D2002001AD /* ListRightVariablePriceChangeBodyTextModel.swift */; };
|
||||||
BB6C6AC0242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6ABE242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift */; };
|
BB6C6AC0242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6ABE242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift */; };
|
||||||
BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6ABF242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift */; };
|
BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6ABF242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift */; };
|
||||||
BB6C6AC824225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6AC62422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift */; };
|
BB6C6AC824225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6AC62422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift */; };
|
||||||
@ -224,9 +245,17 @@
|
|||||||
C7F8012323E846C300396FBD /* ListRVWheelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7F8012223E846C300396FBD /* ListRVWheelModel.swift */; };
|
C7F8012323E846C300396FBD /* ListRVWheelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7F8012223E846C300396FBD /* ListRVWheelModel.swift */; };
|
||||||
D202AFE4242A5F5E00E5BEDF /* NSTextAlignment+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D202AFE3242A5F5E00E5BEDF /* NSTextAlignment+Extension.swift */; };
|
D202AFE4242A5F5E00E5BEDF /* NSTextAlignment+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D202AFE3242A5F5E00E5BEDF /* NSTextAlignment+Extension.swift */; };
|
||||||
D202AFE6242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */; };
|
D202AFE6242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */; };
|
||||||
|
D2092349244A51D40044AD09 /* RadioSwatchModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2092348244A51D40044AD09 /* RadioSwatchModel.swift */; };
|
||||||
|
D209234F244F77FD0044AD09 /* ThreeLayerCenterTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D209234E244F77FD0044AD09 /* ThreeLayerCenterTemplate.swift */; };
|
||||||
|
D2092351244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2092350244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift */; };
|
||||||
|
D2092353244F7D630044AD09 /* MVMCoreUIViewControllerMappingObject+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2092352244F7D630044AD09 /* MVMCoreUIViewControllerMappingObject+Extension.swift */; };
|
||||||
|
D2092355244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */; };
|
||||||
|
D2092357244FA1EF0044AD09 /* ThreeLayerModelBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2092356244FA1EF0044AD09 /* ThreeLayerModelBase.swift */; };
|
||||||
|
D20923592450ECE00044AD09 /* TableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20923582450ECE00044AD09 /* TableView.swift */; };
|
||||||
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; };
|
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; };
|
||||||
D20FB165241A5D75004AFC3A /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */; };
|
D20FB165241A5D75004AFC3A /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */; };
|
||||||
D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; };
|
D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; };
|
||||||
|
D21B7F602437C5BC00051ABF /* MoleculeStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F5E2437C5BC00051ABF /* MoleculeStackView.swift */; };
|
||||||
D21B7F71243BAC1600051ABF /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */; };
|
D21B7F71243BAC1600051ABF /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */; };
|
||||||
D21B7F73243BAC6800051ABF /* CollectionItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F72243BAC6800051ABF /* CollectionItemModelProtocol.swift */; };
|
D21B7F73243BAC6800051ABF /* CollectionItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F72243BAC6800051ABF /* CollectionItemModelProtocol.swift */; };
|
||||||
D21B7F75243BAC8900051ABF /* CarouselItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F74243BAC8900051ABF /* CarouselItem.swift */; };
|
D21B7F75243BAC8900051ABF /* CarouselItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F74243BAC8900051ABF /* CarouselItem.swift */; };
|
||||||
@ -287,7 +316,7 @@
|
|||||||
D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837C23CCA86A00DFE4FC /* TabsListItemModel.swift */; };
|
D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837C23CCA86A00DFE4FC /* TabsListItemModel.swift */; };
|
||||||
D28A837F23CCA96400DFE4FC /* TabsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837E23CCA96400DFE4FC /* TabsModel.swift */; };
|
D28A837F23CCA96400DFE4FC /* TabsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837E23CCA96400DFE4FC /* TabsModel.swift */; };
|
||||||
D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838023CCB0D800DFE4FC /* AccordionListItemModel.swift */; };
|
D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838023CCB0D800DFE4FC /* AccordionListItemModel.swift */; };
|
||||||
D28A838323CCBD3F00DFE4FC /* CircleProgressModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */; };
|
D28A838323CCBD3F00DFE4FC /* WheelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838223CCBD3F00DFE4FC /* WheelModel.swift */; };
|
||||||
D28A838523CCCA8900DFE4FC /* ScrollerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838423CCCA8900DFE4FC /* ScrollerModel.swift */; };
|
D28A838523CCCA8900DFE4FC /* ScrollerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838423CCCA8900DFE4FC /* ScrollerModel.swift */; };
|
||||||
D28A838923CCCFCB00DFE4FC /* LinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838823CCCFCB00DFE4FC /* LinkModel.swift */; };
|
D28A838923CCCFCB00DFE4FC /* LinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838823CCCFCB00DFE4FC /* LinkModel.swift */; };
|
||||||
D28A838B23CCDA6B00DFE4FC /* ButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */; };
|
D28A838B23CCDA6B00DFE4FC /* ButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */; };
|
||||||
@ -395,7 +424,6 @@
|
|||||||
D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29E28D723D21AB800ACEA85 /* StringAndMoleculeView.swift */; };
|
D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29E28D723D21AB800ACEA85 /* StringAndMoleculeView.swift */; };
|
||||||
D29E28DA23D21AFA00ACEA85 /* StringAndMoleculeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29E28D923D21AFA00ACEA85 /* StringAndMoleculeModel.swift */; };
|
D29E28DA23D21AFA00ACEA85 /* StringAndMoleculeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29E28D923D21AFA00ACEA85 /* StringAndMoleculeModel.swift */; };
|
||||||
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29E28DC23D7404C00ACEA85 /* ContainerHelper.swift */; };
|
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29E28DC23D7404C00ACEA85 /* ContainerHelper.swift */; };
|
||||||
D2A5145F2211DDC100345BFB /* MoleculeStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5145E2211DDC100345BFB /* MoleculeStackView.swift */; };
|
|
||||||
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */; };
|
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */; };
|
||||||
D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */; };
|
D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */; };
|
||||||
D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A514662213885800345BFB /* MoleculeHeaderView.swift */; };
|
D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A514662213885800345BFB /* MoleculeHeaderView.swift */; };
|
||||||
@ -499,7 +527,6 @@
|
|||||||
01EB368823609801006832FA /* LabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelModel.swift; sourceTree = "<group>"; };
|
01EB368823609801006832FA /* LabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelModel.swift; sourceTree = "<group>"; };
|
||||||
01EB368923609801006832FA /* MoleculeListItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeListItemModel.swift; sourceTree = "<group>"; };
|
01EB368923609801006832FA /* MoleculeListItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeListItemModel.swift; sourceTree = "<group>"; };
|
||||||
01EB368A23609801006832FA /* MoleculeStackItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackItemModel.swift; sourceTree = "<group>"; };
|
01EB368A23609801006832FA /* MoleculeStackItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackItemModel.swift; sourceTree = "<group>"; };
|
||||||
01EB368B23609801006832FA /* MoleculeStackModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackModel.swift; sourceTree = "<group>"; };
|
|
||||||
01EB368C23609801006832FA /* HeaderModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderModel.swift; sourceTree = "<group>"; };
|
01EB368C23609801006832FA /* HeaderModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderModel.swift; sourceTree = "<group>"; };
|
||||||
01EB368D23609801006832FA /* HeadlineBodyModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeadlineBodyModel.swift; sourceTree = "<group>"; };
|
01EB368D23609801006832FA /* HeadlineBodyModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeadlineBodyModel.swift; sourceTree = "<group>"; };
|
||||||
01F2A03123A4498200D954D8 /* CaretLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaretLinkModel.swift; sourceTree = "<group>"; };
|
01F2A03123A4498200D954D8 /* CaretLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaretLinkModel.swift; sourceTree = "<group>"; };
|
||||||
@ -522,6 +549,7 @@
|
|||||||
0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxLabel.swift; sourceTree = "<group>"; };
|
0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxLabel.swift; sourceTree = "<group>"; };
|
||||||
0A7ECC5C243CE85300C828E8 /* DoughnutChartItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoughnutChartItemModel.swift; sourceTree = "<group>"; };
|
0A7ECC5C243CE85300C828E8 /* DoughnutChartItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoughnutChartItemModel.swift; sourceTree = "<group>"; };
|
||||||
0A7ECC5E243CEB1200C828E8 /* ColorViewWithLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorViewWithLabel.swift; sourceTree = "<group>"; };
|
0A7ECC5E243CEB1200C828E8 /* ColorViewWithLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorViewWithLabel.swift; sourceTree = "<group>"; };
|
||||||
|
0A7ECC6F2441001C00C828E8 /* UIToolbar+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIToolbar+Extension.swift"; sourceTree = "<group>"; };
|
||||||
0A7EF85A23D8A52800B2AAD1 /* EntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFieldModel.swift; sourceTree = "<group>"; };
|
0A7EF85A23D8A52800B2AAD1 /* EntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFieldModel.swift; sourceTree = "<group>"; };
|
||||||
0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryFieldModel.swift; sourceTree = "<group>"; };
|
0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryFieldModel.swift; sourceTree = "<group>"; };
|
||||||
0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MdnEntryFieldModel.swift; sourceTree = "<group>"; };
|
0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MdnEntryFieldModel.swift; sourceTree = "<group>"; };
|
||||||
@ -532,6 +560,8 @@
|
|||||||
0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = "<group>"; };
|
0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = "<group>"; };
|
||||||
0AA33B33239813C50067DD0F /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = "<group>"; };
|
0AA33B33239813C50067DD0F /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = "<group>"; };
|
||||||
0AA33B392398524F0067DD0F /* Toggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toggle.swift; sourceTree = "<group>"; };
|
0AA33B392398524F0067DD0F /* Toggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toggle.swift; sourceTree = "<group>"; };
|
||||||
|
0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDatePicker+Extension.swift"; sourceTree = "<group>"; };
|
||||||
|
0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIPickerView+Extension.swift"; sourceTree = "<group>"; };
|
||||||
0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = "<group>"; };
|
0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = "<group>"; };
|
||||||
0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = "<group>"; };
|
0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = "<group>"; };
|
||||||
0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
|
0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
|
||||||
@ -568,8 +598,12 @@
|
|||||||
8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
||||||
8D4687E1242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageListItemModel.swift; sourceTree = "<group>"; };
|
8D4687E1242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageListItemModel.swift; sourceTree = "<group>"; };
|
||||||
8D4687E3242E2DF300802879 /* ListFourColumnDataUsageListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageListItem.swift; sourceTree = "<group>"; };
|
8D4687E3242E2DF300802879 /* ListFourColumnDataUsageListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageListItem.swift; sourceTree = "<group>"; };
|
||||||
|
8D8067D02444472F00203BE8 /* ListRightVariablePriceChangeAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePriceChangeAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
||||||
|
8D8067D22444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePriceChangeAllTextAndLinks.swift; sourceTree = "<group>"; };
|
||||||
8DD1E36D243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnInternationalDataModel.swift; sourceTree = "<group>"; };
|
8DD1E36D243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnInternationalDataModel.swift; sourceTree = "<group>"; };
|
||||||
8DD1E36F243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnInternationalData.swift; sourceTree = "<group>"; };
|
8DD1E36F243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnInternationalData.swift; sourceTree = "<group>"; };
|
||||||
|
8DDD6C1C244D90B8006A2232 /* ListThreeColumnDataUsage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnDataUsage.swift; sourceTree = "<group>"; };
|
||||||
|
8DDD6C1E244D90E1006A2232 /* ListThreeColumnDataUsageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnDataUsageModel.swift; sourceTree = "<group>"; };
|
||||||
8DEFA95B243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnDataUsageDividerModel.swift; sourceTree = "<group>"; };
|
8DEFA95B243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnDataUsageDividerModel.swift; sourceTree = "<group>"; };
|
||||||
8DEFA95D243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnDataUsageDivider.swift; sourceTree = "<group>"; };
|
8DEFA95D243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnDataUsageDivider.swift; sourceTree = "<group>"; };
|
||||||
9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = "<group>"; };
|
9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = "<group>"; };
|
||||||
@ -578,8 +612,8 @@
|
|||||||
942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalMoleculeListTemplate.swift; 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>"; };
|
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>"; };
|
9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = "<group>"; };
|
||||||
943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = "<group>"; };
|
943784F3236B77BB006A1E82 /* Wheel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Wheel.swift; sourceTree = "<group>"; };
|
||||||
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = "<group>"; };
|
943784F4236B77BB006A1E82 /* WheelAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WheelAnimationHandler.swift; sourceTree = "<group>"; };
|
||||||
943820832432382400B43AF3 /* WebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebView.swift; sourceTree = "<group>"; };
|
943820832432382400B43AF3 /* WebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebView.swift; sourceTree = "<group>"; };
|
||||||
94382085243238D100B43AF3 /* WebViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewModel.swift; sourceTree = "<group>"; };
|
94382085243238D100B43AF3 /* WebViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewModel.swift; sourceTree = "<group>"; };
|
||||||
9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBarModel.swift; sourceTree = "<group>"; };
|
9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBarModel.swift; sourceTree = "<group>"; };
|
||||||
@ -610,6 +644,7 @@
|
|||||||
94CA227B24058533002D6750 /* VerizonNHGeTX-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeTX-Regular.otf"; sourceTree = "<group>"; };
|
94CA227B24058533002D6750 /* VerizonNHGeTX-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeTX-Regular.otf"; sourceTree = "<group>"; };
|
||||||
94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrimaryButtonView.h; sourceTree = "<group>"; };
|
94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrimaryButtonView.h; sourceTree = "<group>"; };
|
||||||
94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PrimaryButtonView.m; sourceTree = "<group>"; };
|
94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PrimaryButtonView.m; sourceTree = "<group>"; };
|
||||||
|
94F6516C2437954100631BF9 /* Tabs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tabs.swift; sourceTree = "<group>"; };
|
||||||
94FB966023D797DA003D482B /* MFTextButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFTextButton.h; sourceTree = "<group>"; };
|
94FB966023D797DA003D482B /* MFTextButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFTextButton.h; sourceTree = "<group>"; };
|
||||||
94FB966123D797DA003D482B /* MFTextButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFTextButton.m; sourceTree = "<group>"; };
|
94FB966123D797DA003D482B /* MFTextButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFTextButton.m; sourceTree = "<group>"; };
|
||||||
AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2Buttons.swift; sourceTree = "<group>"; };
|
AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2Buttons.swift; sourceTree = "<group>"; };
|
||||||
@ -618,16 +653,30 @@
|
|||||||
AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePaymentsModel.swift; sourceTree = "<group>"; };
|
AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePaymentsModel.swift; sourceTree = "<group>"; };
|
||||||
AA1EC59624373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnSpeedTestDividerModel.swift; sourceTree = "<group>"; };
|
AA1EC59624373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnSpeedTestDividerModel.swift; sourceTree = "<group>"; };
|
||||||
AA1EC59824373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnSpeedTestDivider.swift; sourceTree = "<group>"; };
|
AA1EC59824373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnSpeedTestDivider.swift; sourceTree = "<group>"; };
|
||||||
|
AA2AD115244EE46800BBFFE3 /* ListDeviceComplexLinkMedium.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexLinkMedium.swift; sourceTree = "<group>"; };
|
||||||
|
AA2AD117244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexLinkMediumModel.swift; sourceTree = "<group>"; };
|
||||||
AA56A20E243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnSubsectionDividerModel.swift; sourceTree = "<group>"; };
|
AA56A20E243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnSubsectionDividerModel.swift; sourceTree = "<group>"; };
|
||||||
AA56A210243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnSubsectionDivider.swift; sourceTree = "<group>"; };
|
AA56A210243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnSubsectionDivider.swift; sourceTree = "<group>"; };
|
||||||
|
AA617AAF2453010A00910B8F /* ListDeviceComplexLinkSmall.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexLinkSmall.swift; sourceTree = "<group>"; };
|
||||||
|
AA617AB12453012400910B8F /* ListDeviceComplexLinkSmallModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexLinkSmallModel.swift; sourceTree = "<group>"; };
|
||||||
|
AA69AAF52445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxBodyText.swift; sourceTree = "<group>"; };
|
||||||
|
AA69AAF72445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxBodyTextModel.swift; sourceTree = "<group>"; };
|
||||||
|
AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||||
AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyText.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>"; };
|
AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyTextModel.swift; sourceTree = "<group>"; };
|
||||||
|
AAB9C10724346F4B00151545 /* RadioSwatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatches.swift; sourceTree = "<group>"; };
|
||||||
|
AAB9C109243496DD00151545 /* RadioSwatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatch.swift; sourceTree = "<group>"; };
|
||||||
|
AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.swift; sourceTree = "<group>"; };
|
||||||
|
BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMediumModel.swift; sourceTree = "<group>"; };
|
||||||
|
BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMedium.swift; sourceTree = "<group>"; };
|
||||||
BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
||||||
BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinks.swift; sourceTree = "<group>"; };
|
BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinks.swift; sourceTree = "<group>"; };
|
||||||
BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsectionModel.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>"; };
|
BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsection.swift; sourceTree = "<group>"; };
|
||||||
BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableButtonAllTextAndLinks.swift; sourceTree = "<group>"; };
|
BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableButtonAllTextAndLinks.swift; sourceTree = "<group>"; };
|
||||||
BB54C51F2434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableButtonAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
BB54C51F2434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableButtonAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
||||||
|
BB55B51C244482C0002001AD /* ListRightVariablePriceChangeBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePriceChangeBodyText.swift; sourceTree = "<group>"; };
|
||||||
|
BB55B51E244482D2002001AD /* ListRightVariablePriceChangeBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePriceChangeBodyTextModel.swift; sourceTree = "<group>"; };
|
||||||
BB6C6ABE242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerTallModel.swift; sourceTree = "<group>"; };
|
BB6C6ABE242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerTallModel.swift; sourceTree = "<group>"; };
|
||||||
BB6C6ABF242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerTall.swift; sourceTree = "<group>"; };
|
BB6C6ABF242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerTall.swift; sourceTree = "<group>"; };
|
||||||
BB6C6AC62422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerShort.swift; sourceTree = "<group>"; };
|
BB6C6AC62422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerShort.swift; sourceTree = "<group>"; };
|
||||||
@ -652,9 +701,17 @@
|
|||||||
C7F8012223E846C300396FBD /* ListRVWheelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRVWheelModel.swift; sourceTree = "<group>"; };
|
C7F8012223E846C300396FBD /* ListRVWheelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRVWheelModel.swift; sourceTree = "<group>"; };
|
||||||
D202AFE3242A5F5E00E5BEDF /* NSTextAlignment+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSTextAlignment+Extension.swift"; sourceTree = "<group>"; };
|
D202AFE3242A5F5E00E5BEDF /* NSTextAlignment+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSTextAlignment+Extension.swift"; sourceTree = "<group>"; };
|
||||||
D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UICollectionViewScrollPosition+Extension.swift"; sourceTree = "<group>"; };
|
D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UICollectionViewScrollPosition+Extension.swift"; sourceTree = "<group>"; };
|
||||||
|
D2092348244A51D40044AD09 /* RadioSwatchModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchModel.swift; sourceTree = "<group>"; };
|
||||||
|
D209234E244F77FD0044AD09 /* ThreeLayerCenterTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerCenterTemplate.swift; sourceTree = "<group>"; };
|
||||||
|
D2092350244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerCenterTemplateModel.swift; sourceTree = "<group>"; };
|
||||||
|
D2092352244F7D630044AD09 /* MVMCoreUIViewControllerMappingObject+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUIViewControllerMappingObject+Extension.swift"; sourceTree = "<group>"; };
|
||||||
|
D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerTemplateModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
D2092356244FA1EF0044AD09 /* ThreeLayerModelBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerModelBase.swift; sourceTree = "<group>"; };
|
||||||
|
D20923582450ECE00044AD09 /* TableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableView.swift; sourceTree = "<group>"; };
|
||||||
D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = "<group>"; };
|
D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = "<group>"; };
|
||||||
D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = "<group>"; };
|
D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
|
D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
|
||||||
|
D21B7F5E2437C5BC00051ABF /* MoleculeStackView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackView.swift; sourceTree = "<group>"; };
|
||||||
D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = "<group>"; };
|
D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = "<group>"; };
|
||||||
D21B7F72243BAC6800051ABF /* CollectionItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionItemModelProtocol.swift; sourceTree = "<group>"; };
|
D21B7F72243BAC6800051ABF /* CollectionItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionItemModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
D21B7F74243BAC8900051ABF /* CarouselItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItem.swift; sourceTree = "<group>"; };
|
D21B7F74243BAC8900051ABF /* CarouselItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItem.swift; sourceTree = "<group>"; };
|
||||||
@ -714,7 +771,7 @@
|
|||||||
D28A837C23CCA86A00DFE4FC /* TabsListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsListItemModel.swift; sourceTree = "<group>"; };
|
D28A837C23CCA86A00DFE4FC /* TabsListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsListItemModel.swift; sourceTree = "<group>"; };
|
||||||
D28A837E23CCA96400DFE4FC /* TabsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsModel.swift; sourceTree = "<group>"; };
|
D28A837E23CCA96400DFE4FC /* TabsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsModel.swift; sourceTree = "<group>"; };
|
||||||
D28A838023CCB0D800DFE4FC /* AccordionListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccordionListItemModel.swift; sourceTree = "<group>"; };
|
D28A838023CCB0D800DFE4FC /* AccordionListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccordionListItemModel.swift; sourceTree = "<group>"; };
|
||||||
D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleProgressModel.swift; sourceTree = "<group>"; };
|
D28A838223CCBD3F00DFE4FC /* WheelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WheelModel.swift; sourceTree = "<group>"; };
|
||||||
D28A838423CCCA8900DFE4FC /* ScrollerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollerModel.swift; sourceTree = "<group>"; };
|
D28A838423CCCA8900DFE4FC /* ScrollerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollerModel.swift; sourceTree = "<group>"; };
|
||||||
D28A838823CCCFCB00DFE4FC /* LinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkModel.swift; sourceTree = "<group>"; };
|
D28A838823CCCFCB00DFE4FC /* LinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkModel.swift; sourceTree = "<group>"; };
|
||||||
D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonModel.swift; sourceTree = "<group>"; };
|
D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonModel.swift; sourceTree = "<group>"; };
|
||||||
@ -837,7 +894,6 @@
|
|||||||
D29E28D723D21AB800ACEA85 /* StringAndMoleculeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringAndMoleculeView.swift; sourceTree = "<group>"; };
|
D29E28D723D21AB800ACEA85 /* StringAndMoleculeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringAndMoleculeView.swift; sourceTree = "<group>"; };
|
||||||
D29E28D923D21AFA00ACEA85 /* StringAndMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringAndMoleculeModel.swift; sourceTree = "<group>"; };
|
D29E28D923D21AFA00ACEA85 /* StringAndMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringAndMoleculeModel.swift; sourceTree = "<group>"; };
|
||||||
D29E28DC23D7404C00ACEA85 /* ContainerHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerHelper.swift; sourceTree = "<group>"; };
|
D29E28DC23D7404C00ACEA85 /* ContainerHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerHelper.swift; sourceTree = "<group>"; };
|
||||||
D2A5145E2211DDC100345BFB /* MoleculeStackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackView.swift; sourceTree = "<group>"; };
|
|
||||||
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackTemplate.swift; sourceTree = "<group>"; };
|
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackTemplate.swift; sourceTree = "<group>"; };
|
||||||
D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackCenteredTemplate.swift; sourceTree = "<group>"; };
|
D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackCenteredTemplate.swift; sourceTree = "<group>"; };
|
||||||
D2A514662213885800345BFB /* MoleculeHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeHeaderView.swift; sourceTree = "<group>"; };
|
D2A514662213885800345BFB /* MoleculeHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeHeaderView.swift; sourceTree = "<group>"; };
|
||||||
@ -910,6 +966,7 @@
|
|||||||
D28A837823C7D5BC00DFE4FC /* PageModelProtocol.swift */,
|
D28A837823C7D5BC00DFE4FC /* PageModelProtocol.swift */,
|
||||||
011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */,
|
011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */,
|
||||||
D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */,
|
D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */,
|
||||||
|
D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */,
|
||||||
);
|
);
|
||||||
path = ModelProtocols;
|
path = ModelProtocols;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1051,6 +1108,8 @@
|
|||||||
children = (
|
children = (
|
||||||
8DD1E36D243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift */,
|
8DD1E36D243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift */,
|
||||||
8DD1E36F243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift */,
|
8DD1E36F243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift */,
|
||||||
|
8DDD6C1E244D90E1006A2232 /* ListThreeColumnDataUsageModel.swift */,
|
||||||
|
8DDD6C1C244D90B8006A2232 /* ListThreeColumnDataUsage.swift */,
|
||||||
);
|
);
|
||||||
path = ThreeColumn;
|
path = ThreeColumn;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1099,6 +1158,10 @@
|
|||||||
AA11A41E23F15D3100D7962F /* ListRightVariablePayments.swift */,
|
AA11A41E23F15D3100D7962F /* ListRightVariablePayments.swift */,
|
||||||
8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */,
|
8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */,
|
||||||
8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */,
|
8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */,
|
||||||
|
BB55B51E244482D2002001AD /* ListRightVariablePriceChangeBodyTextModel.swift */,
|
||||||
|
BB55B51C244482C0002001AD /* ListRightVariablePriceChangeBodyText.swift */,
|
||||||
|
8D8067D02444472F00203BE8 /* ListRightVariablePriceChangeAllTextAndLinksModel.swift */,
|
||||||
|
8D8067D22444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift */,
|
||||||
C7F8012223E846C300396FBD /* ListRVWheelModel.swift */,
|
C7F8012223E846C300396FBD /* ListRVWheelModel.swift */,
|
||||||
C7F8012023E8303200396FBD /* ListRVWheel.swift */,
|
C7F8012023E8303200396FBD /* ListRVWheel.swift */,
|
||||||
);
|
);
|
||||||
@ -1122,6 +1185,9 @@
|
|||||||
D21EE53B23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift */,
|
D21EE53B23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift */,
|
||||||
D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */,
|
D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */,
|
||||||
013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */,
|
013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */,
|
||||||
|
0A7ECC6F2441001C00C828E8 /* UIToolbar+Extension.swift */,
|
||||||
|
0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */,
|
||||||
|
0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */,
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1135,6 +1201,19 @@
|
|||||||
path = FourColumn;
|
path = FourColumn;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
D20FFFB42451E32100A31DA2 /* Device */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */,
|
||||||
|
BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */,
|
||||||
|
AA617AB12453012400910B8F /* ListDeviceComplexLinkSmallModel.swift */,
|
||||||
|
AA617AAF2453010A00910B8F /* ListDeviceComplexLinkSmall.swift */,
|
||||||
|
AA2AD117244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift */,
|
||||||
|
AA2AD115244EE46800BBFFE3 /* ListDeviceComplexLinkMedium.swift */,
|
||||||
|
);
|
||||||
|
path = Device;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
D213347423842FE3008E41B3 /* Controllers */ = {
|
D213347423842FE3008E41B3 /* Controllers */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -1263,6 +1342,7 @@
|
|||||||
D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */,
|
D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */,
|
||||||
D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */,
|
D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */,
|
||||||
D28A837E23CCA96400DFE4FC /* TabsModel.swift */,
|
D28A837E23CCA96400DFE4FC /* TabsModel.swift */,
|
||||||
|
94F6516C2437954100631BF9 /* Tabs.swift */,
|
||||||
011D9625240EBB16000E3791 /* RadioButtonLabelModel.swift */,
|
011D9625240EBB16000E3791 /* RadioButtonLabelModel.swift */,
|
||||||
017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */,
|
017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */,
|
||||||
);
|
);
|
||||||
@ -1287,8 +1367,7 @@
|
|||||||
D260105A23D0BB7100764D80 /* StackModelProtocol.swift */,
|
D260105A23D0BB7100764D80 /* StackModelProtocol.swift */,
|
||||||
D260106423D0CEA700764D80 /* StackModel.swift */,
|
D260106423D0CEA700764D80 /* StackModel.swift */,
|
||||||
D260105C23D0BCD400764D80 /* Stack.swift */,
|
D260105C23D0BCD400764D80 /* Stack.swift */,
|
||||||
01EB368B23609801006832FA /* MoleculeStackModel.swift */,
|
D21B7F5E2437C5BC00051ABF /* MoleculeStackView.swift */,
|
||||||
D2A5145E2211DDC100345BFB /* MoleculeStackView.swift */,
|
|
||||||
012A88AE238C626E00FE3DA1 /* CarouselModel.swift */,
|
012A88AE238C626E00FE3DA1 /* CarouselModel.swift */,
|
||||||
D2A6390022CBB1820052ED1F /* Carousel.swift */,
|
D2A6390022CBB1820052ED1F /* Carousel.swift */,
|
||||||
);
|
);
|
||||||
@ -1334,6 +1413,7 @@
|
|||||||
D22B38EA23F4E08B00490EF6 /* List */ = {
|
D22B38EA23F4E08B00490EF6 /* List */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
D20FFFB42451E32100A31DA2 /* Device */,
|
||||||
52267A0523FFE0A900906CBA /* OneColumn */,
|
52267A0523FFE0A900906CBA /* OneColumn */,
|
||||||
D22D8396241FDE4700D3DF69 /* TwoColumn */,
|
D22D8396241FDE4700D3DF69 /* TwoColumn */,
|
||||||
8DD1E36C243B3CD900D8F2DF /* ThreeColumn */,
|
8DD1E36C243B3CD900D8F2DF /* ThreeColumn */,
|
||||||
@ -1349,6 +1429,8 @@
|
|||||||
children = (
|
children = (
|
||||||
52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */,
|
52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */,
|
||||||
52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */,
|
52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */,
|
||||||
|
AA69AAF72445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift */,
|
||||||
|
AA69AAF52445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift */,
|
||||||
522679C023FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift */,
|
522679C023FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift */,
|
||||||
522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */,
|
522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */,
|
||||||
8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */,
|
8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */,
|
||||||
@ -1435,6 +1517,11 @@
|
|||||||
01004F2F22721C3800991ECC /* RadioButton.swift */,
|
01004F2F22721C3800991ECC /* RadioButton.swift */,
|
||||||
31BE15CA23D8924C00452370 /* CheckboxModel.swift */,
|
31BE15CA23D8924C00452370 /* CheckboxModel.swift */,
|
||||||
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */,
|
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */,
|
||||||
|
AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */,
|
||||||
|
AAB9C10724346F4B00151545 /* RadioSwatches.swift */,
|
||||||
|
D2092348244A51D40044AD09 /* RadioSwatchModel.swift */,
|
||||||
|
AAB9C109243496DD00151545 /* RadioSwatch.swift */,
|
||||||
|
AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */,
|
||||||
);
|
);
|
||||||
path = Selectors;
|
path = Selectors;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1484,6 +1571,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D22D8392241C27B100D3DF69 /* TemplateModel.swift */,
|
D22D8392241C27B100D3DF69 /* TemplateModel.swift */,
|
||||||
|
D2092356244FA1EF0044AD09 /* ThreeLayerModelBase.swift */,
|
||||||
014AA72823C5059B006F3E93 /* StackPageTemplateModel.swift */,
|
014AA72823C5059B006F3E93 /* StackPageTemplateModel.swift */,
|
||||||
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */,
|
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */,
|
||||||
942C378D2412F5B60066E45E /* ModalMoleculeStackTemplate.swift */,
|
942C378D2412F5B60066E45E /* ModalMoleculeStackTemplate.swift */,
|
||||||
@ -1495,6 +1583,8 @@
|
|||||||
942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */,
|
942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */,
|
||||||
014AA72A23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift */,
|
014AA72A23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift */,
|
||||||
D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */,
|
D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */,
|
||||||
|
D2092350244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift */,
|
||||||
|
D209234E244F77FD0044AD09 /* ThreeLayerCenterTemplate.swift */,
|
||||||
D264FAA4243F66A500D98315 /* CollectionTemplateItemProtocol.swift */,
|
D264FAA4243F66A500D98315 /* CollectionTemplateItemProtocol.swift */,
|
||||||
D264FA8B243BCD8E00D98315 /* CollectionTemplateModel.swift */,
|
D264FA8B243BCD8E00D98315 /* CollectionTemplateModel.swift */,
|
||||||
D264FA8D243BCD9A00D98315 /* CollectionTemplate.swift */,
|
D264FA8D243BCD9A00D98315 /* CollectionTemplate.swift */,
|
||||||
@ -1682,9 +1772,9 @@
|
|||||||
94C2D9822386F3E30006CF46 /* Label */,
|
94C2D9822386F3E30006CF46 /* Label */,
|
||||||
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */,
|
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */,
|
||||||
0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */,
|
0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */,
|
||||||
D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */,
|
D28A838223CCBD3F00DFE4FC /* WheelModel.swift */,
|
||||||
943784F3236B77BB006A1E82 /* GraphView.swift */,
|
943784F3236B77BB006A1E82 /* Wheel.swift */,
|
||||||
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */,
|
943784F4236B77BB006A1E82 /* WheelAnimationHandler.swift */,
|
||||||
D260105223CEA61600764D80 /* ToggleModel.swift */,
|
D260105223CEA61600764D80 /* ToggleModel.swift */,
|
||||||
0AA33B392398524F0067DD0F /* Toggle.swift */,
|
0AA33B392398524F0067DD0F /* Toggle.swift */,
|
||||||
0AE98BB623FF18E9004C5109 /* ArrowModel.swift */,
|
0AE98BB623FF18E9004C5109 /* ArrowModel.swift */,
|
||||||
@ -1747,6 +1837,7 @@
|
|||||||
D29DF27421E79E81003B2FB9 /* MVMCoreUILoggingHandler.m */,
|
D29DF27421E79E81003B2FB9 /* MVMCoreUILoggingHandler.m */,
|
||||||
D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */,
|
D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */,
|
||||||
D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */,
|
D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */,
|
||||||
|
D2092352244F7D630044AD09 /* MVMCoreUIViewControllerMappingObject+Extension.swift */,
|
||||||
D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */,
|
D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */,
|
||||||
);
|
);
|
||||||
path = OtherHandlers;
|
path = OtherHandlers;
|
||||||
@ -1852,6 +1943,7 @@
|
|||||||
D2B18B7E2360913400A9AEDC /* Control.swift */,
|
D2B18B7E2360913400A9AEDC /* Control.swift */,
|
||||||
D2B18B802360945C00A9AEDC /* View.swift */,
|
D2B18B802360945C00A9AEDC /* View.swift */,
|
||||||
0AE14F63238315D2005417F8 /* TextField.swift */,
|
0AE14F63238315D2005417F8 /* TextField.swift */,
|
||||||
|
D20923582450ECE00044AD09 /* TableView.swift */,
|
||||||
D2755D7A23689C7500485468 /* TableViewCell.swift */,
|
D2755D7A23689C7500485468 /* TableViewCell.swift */,
|
||||||
D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */,
|
D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */,
|
||||||
D264FAA92440F97600D98315 /* CollectionView.swift */,
|
D264FAA92440F97600D98315 /* CollectionView.swift */,
|
||||||
@ -2046,10 +2138,11 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */,
|
||||||
5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */,
|
5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */,
|
||||||
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
|
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
|
||||||
8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */,
|
8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */,
|
||||||
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */,
|
943784F5236B77BB006A1E82 /* Wheel.swift in Sources */,
|
||||||
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */,
|
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */,
|
||||||
8D3BA9BF2433789900D341BA /* ListThreeColumnInternationalDataDivider.swift in Sources */,
|
8D3BA9BF2433789900D341BA /* ListThreeColumnInternationalDataDivider.swift in Sources */,
|
||||||
94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */,
|
94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */,
|
||||||
@ -2062,6 +2155,7 @@
|
|||||||
D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */,
|
D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */,
|
||||||
D28A838923CCCFCB00DFE4FC /* LinkModel.swift in Sources */,
|
D28A838923CCCFCB00DFE4FC /* LinkModel.swift in Sources */,
|
||||||
AA56A20F243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift in Sources */,
|
AA56A20F243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift in Sources */,
|
||||||
|
AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */,
|
||||||
94C2D9A923872E5E0006CF46 /* LabelAttributeImageModel.swift in Sources */,
|
94C2D9A923872E5E0006CF46 /* LabelAttributeImageModel.swift in Sources */,
|
||||||
DBC4391922442197001AB423 /* DashLine.swift in Sources */,
|
DBC4391922442197001AB423 /* DashLine.swift in Sources */,
|
||||||
D264FAAA2440F97600D98315 /* CollectionView.swift in Sources */,
|
D264FAAA2440F97600D98315 /* CollectionView.swift in Sources */,
|
||||||
@ -2070,12 +2164,15 @@
|
|||||||
AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */,
|
AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */,
|
||||||
D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */,
|
D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */,
|
||||||
0116A4E5228B19640094F3ED /* RadioButtonSelectionHelper.swift in Sources */,
|
0116A4E5228B19640094F3ED /* RadioButtonSelectionHelper.swift in Sources */,
|
||||||
|
D2092353244F7D630044AD09 /* MVMCoreUIViewControllerMappingObject+Extension.swift in Sources */,
|
||||||
017BEB48236230DB0024EF95 /* MoleculeViewProtocol.swift in Sources */,
|
017BEB48236230DB0024EF95 /* MoleculeViewProtocol.swift in Sources */,
|
||||||
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */,
|
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */,
|
||||||
94382086243238D100B43AF3 /* WebViewModel.swift in Sources */,
|
94382086243238D100B43AF3 /* WebViewModel.swift in Sources */,
|
||||||
D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */,
|
D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */,
|
||||||
D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */,
|
D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */,
|
||||||
|
D21B7F602437C5BC00051ABF /* MoleculeStackView.swift in Sources */,
|
||||||
0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */,
|
0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */,
|
||||||
|
AA2AD116244EE46800BBFFE3 /* ListDeviceComplexLinkMedium.swift in Sources */,
|
||||||
D22D1F1F220343560077CEC0 /* MVMCoreUICheckMarkView.m in Sources */,
|
D22D1F1F220343560077CEC0 /* MVMCoreUICheckMarkView.m in Sources */,
|
||||||
D2E2A99423D8CCBC000B42E6 /* HeadlineBodyLinkModel.swift in Sources */,
|
D2E2A99423D8CCBC000B42E6 /* HeadlineBodyLinkModel.swift in Sources */,
|
||||||
01004F3022721C3800991ECC /* RadioButton.swift in Sources */,
|
01004F3022721C3800991ECC /* RadioButton.swift in Sources */,
|
||||||
@ -2091,6 +2188,7 @@
|
|||||||
942C378C2412F4FA0066E45E /* ModalMoleculeListTemplate.swift in Sources */,
|
942C378C2412F4FA0066E45E /* ModalMoleculeListTemplate.swift in Sources */,
|
||||||
BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */,
|
BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */,
|
||||||
012A88C8238DB02000FE3DA1 /* MoleculeDelegateProtocol.swift in Sources */,
|
012A88C8238DB02000FE3DA1 /* MoleculeDelegateProtocol.swift in Sources */,
|
||||||
|
8D8067D12444472F00203BE8 /* ListRightVariablePriceChangeAllTextAndLinksModel.swift in Sources */,
|
||||||
0A7EF86123D8AC2500B2AAD1 /* DigitEntryFieldModel.swift in Sources */,
|
0A7EF86123D8AC2500B2AAD1 /* DigitEntryFieldModel.swift in Sources */,
|
||||||
DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */,
|
DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */,
|
||||||
D224798C231450C8003FCCF9 /* HeadlineBodyToggle.swift in Sources */,
|
D224798C231450C8003FCCF9 /* HeadlineBodyToggle.swift in Sources */,
|
||||||
@ -2105,10 +2203,13 @@
|
|||||||
D2E2A98323D8B32D000B42E6 /* EyebrowHeadlineBodyLinkModel.swift in Sources */,
|
D2E2A98323D8B32D000B42E6 /* EyebrowHeadlineBodyLinkModel.swift in Sources */,
|
||||||
012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */,
|
012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */,
|
||||||
BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */,
|
BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */,
|
||||||
|
D2092351244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift in Sources */,
|
||||||
D21B7F77243BB70700051ABF /* MoleculeCollectionItemModel.swift in Sources */,
|
D21B7F77243BB70700051ABF /* MoleculeCollectionItemModel.swift in Sources */,
|
||||||
|
AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */,
|
||||||
D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */,
|
D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */,
|
||||||
011D9602240DA20A000E3791 /* FormRuleWatcherFieldProtocol.swift in Sources */,
|
011D9602240DA20A000E3791 /* FormRuleWatcherFieldProtocol.swift in Sources */,
|
||||||
D264FAA1243CF66B00D98315 /* ContainerCollectionReusableView.swift in Sources */,
|
D264FAA1243CF66B00D98315 /* ContainerCollectionReusableView.swift in Sources */,
|
||||||
|
AA617AB22453012400910B8F /* ListDeviceComplexLinkSmallModel.swift in Sources */,
|
||||||
D260106323D0C05000764D80 /* StackItemModel.swift in Sources */,
|
D260106323D0C05000764D80 /* StackItemModel.swift in Sources */,
|
||||||
D2E2A99823D8D63C000B42E6 /* ActionDetailWithImageModel.swift in Sources */,
|
D2E2A99823D8D63C000B42E6 /* ActionDetailWithImageModel.swift in Sources */,
|
||||||
BBBBC87D24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift in Sources */,
|
BBBBC87D24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift in Sources */,
|
||||||
@ -2120,6 +2221,7 @@
|
|||||||
D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */,
|
D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */,
|
||||||
D29DF12E21E6851E003B2FB9 /* MVMCoreUITopAlertView.m in Sources */,
|
D29DF12E21E6851E003B2FB9 /* MVMCoreUITopAlertView.m in Sources */,
|
||||||
AA1EC59724373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift in Sources */,
|
AA1EC59724373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift in Sources */,
|
||||||
|
BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */,
|
||||||
D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */,
|
D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */,
|
||||||
D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */,
|
D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */,
|
||||||
014AA72F23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift in Sources */,
|
014AA72F23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift in Sources */,
|
||||||
@ -2128,7 +2230,6 @@
|
|||||||
D22D1F572204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m in Sources */,
|
D22D1F572204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m in Sources */,
|
||||||
D28A838B23CCDA6B00DFE4FC /* ButtonModel.swift in Sources */,
|
D28A838B23CCDA6B00DFE4FC /* ButtonModel.swift in Sources */,
|
||||||
D21B7F71243BAC1600051ABF /* CollectionViewCell.swift in Sources */,
|
D21B7F71243BAC1600051ABF /* CollectionViewCell.swift in Sources */,
|
||||||
D2A5145F2211DDC100345BFB /* MoleculeStackView.swift in Sources */,
|
|
||||||
C7F8012323E846C300396FBD /* ListRVWheelModel.swift in Sources */,
|
C7F8012323E846C300396FBD /* ListRVWheelModel.swift in Sources */,
|
||||||
D29DF27621E79E81003B2FB9 /* MVMCoreUILoggingHandler.m in Sources */,
|
D29DF27621E79E81003B2FB9 /* MVMCoreUILoggingHandler.m in Sources */,
|
||||||
C695A69623C990BC00BFB94E /* DoughnutChart.swift in Sources */,
|
C695A69623C990BC00BFB94E /* DoughnutChart.swift in Sources */,
|
||||||
@ -2155,8 +2256,8 @@
|
|||||||
0A21DB85235E06EF00C160A2 /* MFTextField.m in Sources */,
|
0A21DB85235E06EF00C160A2 /* MFTextField.m in Sources */,
|
||||||
014AA72623C501E2006F3E93 /* ContainerModelProtocol.swift in Sources */,
|
014AA72623C501E2006F3E93 /* ContainerModelProtocol.swift in Sources */,
|
||||||
AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */,
|
AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */,
|
||||||
01EB369223609801006832FA /* MoleculeStackModel.swift in Sources */,
|
|
||||||
011D9626240EBB16000E3791 /* RadioButtonLabelModel.swift in Sources */,
|
011D9626240EBB16000E3791 /* RadioButtonLabelModel.swift in Sources */,
|
||||||
|
8DDD6C1D244D90B8006A2232 /* ListThreeColumnDataUsage.swift in Sources */,
|
||||||
AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */,
|
AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */,
|
||||||
D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */,
|
D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */,
|
||||||
944589232385DA9600DE9FD4 /* ImageViewModel.swift in Sources */,
|
944589232385DA9600DE9FD4 /* ImageViewModel.swift in Sources */,
|
||||||
@ -2165,10 +2266,12 @@
|
|||||||
525019DE2406430800EED91C /* ListProgressBarData.swift in Sources */,
|
525019DE2406430800EED91C /* ListProgressBarData.swift in Sources */,
|
||||||
D28A837F23CCA96400DFE4FC /* TabsModel.swift in Sources */,
|
D28A837F23CCA96400DFE4FC /* TabsModel.swift in Sources */,
|
||||||
012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */,
|
012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */,
|
||||||
|
8DDD6C1F244D90E1006A2232 /* ListThreeColumnDataUsageModel.swift in Sources */,
|
||||||
|
BB55B51F244482D2002001AD /* ListRightVariablePriceChangeBodyTextModel.swift in Sources */,
|
||||||
D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */,
|
D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */,
|
||||||
D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */,
|
D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */,
|
||||||
01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */,
|
01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */,
|
||||||
D28A838323CCBD3F00DFE4FC /* CircleProgressModel.swift in Sources */,
|
D28A838323CCBD3F00DFE4FC /* WheelModel.swift in Sources */,
|
||||||
EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */,
|
EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */,
|
||||||
D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */,
|
D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */,
|
||||||
DBEFFA04225A829700230692 /* Label.swift in Sources */,
|
DBEFFA04225A829700230692 /* Label.swift in Sources */,
|
||||||
@ -2182,19 +2285,25 @@
|
|||||||
01509D952327ED1900EF99AA /* HeadlineBodyLinkToggle.swift in Sources */,
|
01509D952327ED1900EF99AA /* HeadlineBodyLinkToggle.swift in Sources */,
|
||||||
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */,
|
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */,
|
||||||
D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */,
|
D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */,
|
||||||
|
94F6516D2437954100631BF9 /* Tabs.swift in Sources */,
|
||||||
5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */,
|
5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */,
|
||||||
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */,
|
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */,
|
||||||
D264FA8E243BCD9A00D98315 /* CollectionTemplate.swift in Sources */,
|
D264FA8E243BCD9A00D98315 /* CollectionTemplate.swift in Sources */,
|
||||||
0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */,
|
0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */,
|
||||||
8DEFA95C243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift in Sources */,
|
8DEFA95C243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift in Sources */,
|
||||||
94F217B723E0BF6100A47C06 /* PrimaryButtonView.m in Sources */,
|
94F217B723E0BF6100A47C06 /* PrimaryButtonView.m in Sources */,
|
||||||
|
D2092357244FA1EF0044AD09 /* ThreeLayerModelBase.swift in Sources */,
|
||||||
0A1B4A96233BB18F005B3FB4 /* CheckboxLabel.swift in Sources */,
|
0A1B4A96233BB18F005B3FB4 /* CheckboxLabel.swift in Sources */,
|
||||||
0A21DB8B235E06EF00C160A2 /* MFDigitTextBox.m in Sources */,
|
0A21DB8B235E06EF00C160A2 /* MFDigitTextBox.m in Sources */,
|
||||||
|
D20923592450ECE00044AD09 /* TableView.swift in Sources */,
|
||||||
D260D7B222D65BDD007E7233 /* MVMCoreUIPageControl.m in Sources */,
|
D260D7B222D65BDD007E7233 /* MVMCoreUIPageControl.m in Sources */,
|
||||||
BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */,
|
BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */,
|
||||||
|
AA69AAF82445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.swift in Sources */,
|
||||||
D2B18B812360945C00A9AEDC /* View.swift in Sources */,
|
D2B18B812360945C00A9AEDC /* View.swift in Sources */,
|
||||||
C6FA7D5423C77A4A00A3614A /* NumberedList.swift in Sources */,
|
C6FA7D5423C77A4A00A3614A /* NumberedList.swift in Sources */,
|
||||||
|
0A7ECC702441001C00C828E8 /* UIToolbar+Extension.swift in Sources */,
|
||||||
D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */,
|
D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */,
|
||||||
|
D209234F244F77FD0044AD09 /* ThreeLayerCenterTemplate.swift in Sources */,
|
||||||
525019E52406852100EED91C /* ListFourColumnDataUsageDividerModel.swift in Sources */,
|
525019E52406852100EED91C /* ListFourColumnDataUsageDividerModel.swift in Sources */,
|
||||||
0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */,
|
0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */,
|
||||||
94FB966323D797DA003D482B /* MFTextButton.m in Sources */,
|
94FB966323D797DA003D482B /* MFTextButton.m in Sources */,
|
||||||
@ -2210,12 +2319,14 @@
|
|||||||
D260105D23D0BCD400764D80 /* Stack.swift in Sources */,
|
D260105D23D0BCD400764D80 /* Stack.swift in Sources */,
|
||||||
0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */,
|
0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */,
|
||||||
BB54C5212434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift in Sources */,
|
BB54C5212434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift in Sources */,
|
||||||
|
D2092349244A51D40044AD09 /* RadioSwatchModel.swift in Sources */,
|
||||||
8DD1E370243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift in Sources */,
|
8DD1E370243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift in Sources */,
|
||||||
D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */,
|
D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */,
|
||||||
01EB368F23609801006832FA /* LabelModel.swift in Sources */,
|
01EB368F23609801006832FA /* LabelModel.swift in Sources */,
|
||||||
0A6682AC243531C300AD3CA1 /* Padding.swift in Sources */,
|
0A6682AC243531C300AD3CA1 /* Padding.swift in Sources */,
|
||||||
AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */,
|
AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */,
|
||||||
942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */,
|
942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */,
|
||||||
|
8D8067D32444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift in Sources */,
|
||||||
8D4687E4242E2DF300802879 /* ListFourColumnDataUsageListItem.swift in Sources */,
|
8D4687E4242E2DF300802879 /* ListFourColumnDataUsageListItem.swift in Sources */,
|
||||||
01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */,
|
01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */,
|
||||||
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */,
|
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */,
|
||||||
@ -2223,6 +2334,7 @@
|
|||||||
D22479962316AF6E003FCCF9 /* HeadlineBodyLink.swift in Sources */,
|
D22479962316AF6E003FCCF9 /* HeadlineBodyLink.swift in Sources */,
|
||||||
D29DF2AE21E7B3A4003B2FB9 /* MFTextView.m in Sources */,
|
D29DF2AE21E7B3A4003B2FB9 /* MFTextView.m in Sources */,
|
||||||
0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */,
|
0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */,
|
||||||
|
BB55B51D244482C1002001AD /* ListRightVariablePriceChangeBodyText.swift in Sources */,
|
||||||
017BEB382360C6AC0024EF95 /* RadioButtonLabel.swift in Sources */,
|
017BEB382360C6AC0024EF95 /* RadioButtonLabel.swift in Sources */,
|
||||||
D29DF18121E69E50003B2FB9 /* MFView.m in Sources */,
|
D29DF18121E69E50003B2FB9 /* MFView.m in Sources */,
|
||||||
D28A837923C7D5BC00DFE4FC /* PageModelProtocol.swift in Sources */,
|
D28A837923C7D5BC00DFE4FC /* PageModelProtocol.swift in Sources */,
|
||||||
@ -2246,6 +2358,7 @@
|
|||||||
C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */,
|
C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */,
|
||||||
011D958524042432000E3791 /* RulesProtocol.swift in Sources */,
|
011D958524042432000E3791 /* RulesProtocol.swift in Sources */,
|
||||||
94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */,
|
94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */,
|
||||||
|
AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */,
|
||||||
D264FAA3243E632F00D98315 /* ProgrammaticCollectionViewController.swift in Sources */,
|
D264FAA3243E632F00D98315 /* ProgrammaticCollectionViewController.swift in Sources */,
|
||||||
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
|
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
|
||||||
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */,
|
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */,
|
||||||
@ -2281,6 +2394,7 @@
|
|||||||
525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */,
|
525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */,
|
||||||
0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */,
|
0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */,
|
||||||
D20FB165241A5D75004AFC3A /* NavigationItemModelProtocol.swift in Sources */,
|
D20FB165241A5D75004AFC3A /* NavigationItemModelProtocol.swift in Sources */,
|
||||||
|
AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */,
|
||||||
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */,
|
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */,
|
||||||
0A21DB89235E06EF00C160A2 /* MFMdnTextField.m in Sources */,
|
0A21DB89235E06EF00C160A2 /* MFMdnTextField.m in Sources */,
|
||||||
D224798A2314445E003FCCF9 /* LabelToggle.swift in Sources */,
|
D224798A2314445E003FCCF9 /* LabelToggle.swift in Sources */,
|
||||||
@ -2293,9 +2407,12 @@
|
|||||||
94C0150A24215643005811A9 /* ActionTopAlertModel.swift in Sources */,
|
94C0150A24215643005811A9 /* ActionTopAlertModel.swift in Sources */,
|
||||||
012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */,
|
012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */,
|
||||||
D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */,
|
D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */,
|
||||||
|
D2092355244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift in Sources */,
|
||||||
0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
|
0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
|
||||||
|
0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */,
|
||||||
D29DF17B21E69E1F003B2FB9 /* PrimaryButton.m in Sources */,
|
D29DF17B21E69E1F003B2FB9 /* PrimaryButton.m in Sources */,
|
||||||
D2C78CD224228BBD00B69FDE /* ActionOpenPanelModel.swift in Sources */,
|
D2C78CD224228BBD00B69FDE /* ActionOpenPanelModel.swift in Sources */,
|
||||||
|
AA617AB02453010A00910B8F /* ListDeviceComplexLinkSmall.swift in Sources */,
|
||||||
C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */,
|
C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */,
|
||||||
01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */,
|
01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */,
|
||||||
D27CD4102339057800C1DC07 /* EyebrowHeadlineBodyLink.swift in Sources */,
|
D27CD4102339057800C1DC07 /* EyebrowHeadlineBodyLink.swift in Sources */,
|
||||||
@ -2324,11 +2441,12 @@
|
|||||||
0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */,
|
0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */,
|
||||||
AA56A211243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift in Sources */,
|
AA56A211243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift in Sources */,
|
||||||
D264FA8C243BCD8E00D98315 /* CollectionTemplateModel.swift in Sources */,
|
D264FA8C243BCD8E00D98315 /* CollectionTemplateModel.swift in Sources */,
|
||||||
|
AA85236C244435A20059CC1E /* RadioSwatchCollectionViewCell.swift in Sources */,
|
||||||
52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */,
|
52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */,
|
||||||
D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */,
|
D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */,
|
||||||
0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */,
|
0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */,
|
||||||
94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */,
|
94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */,
|
||||||
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */,
|
943784F6236B77BB006A1E82 /* WheelAnimationHandler.swift in Sources */,
|
||||||
011D95A1240453D0000E3791 /* RuleEqualsModel.swift in Sources */,
|
011D95A1240453D0000E3791 /* RuleEqualsModel.swift in Sources */,
|
||||||
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
|
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
|
||||||
011D95892404249B000E3791 /* FormHolderModelProtocol.swift in Sources */,
|
011D95892404249B000E3791 /* FormHolderModelProtocol.swift in Sources */,
|
||||||
@ -2360,6 +2478,7 @@
|
|||||||
AA104B1A24474A66004D2810 /* HeadersH2Buttons.swift in Sources */,
|
AA104B1A24474A66004D2810 /* HeadersH2Buttons.swift in Sources */,
|
||||||
C7192E7D23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift in Sources */,
|
C7192E7D23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift in Sources */,
|
||||||
D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */,
|
D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */,
|
||||||
|
BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */,
|
||||||
D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */,
|
D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */,
|
||||||
0A7EF86323D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift in Sources */,
|
0A7EF86323D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift in Sources */,
|
||||||
0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */,
|
0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */,
|
||||||
@ -2376,6 +2495,7 @@
|
|||||||
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */,
|
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */,
|
||||||
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
|
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
|
||||||
012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */,
|
012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */,
|
||||||
|
0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */,
|
||||||
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,
|
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,
|
||||||
94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */,
|
94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */,
|
||||||
011D95AB2405C553000E3791 /* FormItemProtocol.swift in Sources */,
|
011D95AB2405C553000E3791 /* FormItemProtocol.swift in Sources */,
|
||||||
|
|||||||
@ -9,9 +9,14 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@objcMembers public class ActionCollapseNotificationModel: ActionModelProtocol {
|
@objcMembers public class ActionCollapseNotificationModel: ActionModelProtocol {
|
||||||
|
|
||||||
public static var identifier: String = "collapseNotification"
|
public static var identifier: String = "collapseNotification"
|
||||||
public var actionType: String
|
public var actionType: String = ActionCollapseNotificationModel.identifier
|
||||||
public var extraParameters: JSONValueDictionary?
|
public var extraParameters: JSONValueDictionary?
|
||||||
public var analyticsData: JSONValueDictionary?
|
public var analyticsData: JSONValueDictionary?
|
||||||
public var title: String?
|
|
||||||
|
public init(_ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
|
||||||
|
self.extraParameters = extraParameters
|
||||||
|
self.analyticsData = analyticsData
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public class ActionOpenPanelModel: ActionModelProtocol {
|
public class ActionOpenPanelModel: ActionModelProtocol {
|
||||||
|
|
||||||
public enum Panel: String, Codable {
|
public enum Panel: String, Codable {
|
||||||
case left
|
case left
|
||||||
case right
|
case right
|
||||||
@ -22,10 +22,10 @@ public class ActionOpenPanelModel: ActionModelProtocol {
|
|||||||
public var panel: Panel
|
public var panel: Panel
|
||||||
public var extraParameters: JSONValueDictionary?
|
public var extraParameters: JSONValueDictionary?
|
||||||
public var analyticsData: JSONValueDictionary?
|
public var analyticsData: JSONValueDictionary?
|
||||||
// Temporary fix till server changes
|
|
||||||
public var title: String?
|
|
||||||
|
|
||||||
public init(panel: Panel) {
|
public init(panel: Panel, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
|
||||||
self.panel = panel
|
self.panel = panel
|
||||||
|
self.extraParameters = extraParameters
|
||||||
|
self.analyticsData = analyticsData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,15 +9,16 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class ActionTopAlertModel: ActionModelProtocol {
|
@objcMembers public class ActionTopAlertModel: ActionModelProtocol {
|
||||||
|
|
||||||
public static var identifier: String = "topAlert"
|
public static var identifier: String = "topAlert"
|
||||||
public var actionType: String = ActionTopAlertModel.identifier
|
public var actionType: String = ActionTopAlertModel.identifier
|
||||||
public var pageType: String
|
public var pageType: String
|
||||||
public var extraParameters: JSONValueDictionary?
|
public var extraParameters: JSONValueDictionary?
|
||||||
public var analyticsData: JSONValueDictionary?
|
public var analyticsData: JSONValueDictionary?
|
||||||
// Temporary fix till server changes
|
|
||||||
public var title: String?
|
|
||||||
|
|
||||||
public init(pageType: String) {
|
public init(pageType: String, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
|
||||||
self.pageType = pageType
|
self.pageType = pageType
|
||||||
|
self.extraParameters = extraParameters
|
||||||
|
self.analyticsData = analyticsData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,7 @@ open class ExternalLink: Link {
|
|||||||
|
|
||||||
guard let model = model as? ExternalLinkModel else { return }
|
guard let model = model as? ExternalLinkModel else { return }
|
||||||
|
|
||||||
exportImageView?.tintColor = model.textColor.uiColor
|
exportImageView?.tintColor = model.enabledColor.uiColor
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -52,7 +52,7 @@ import UIKit
|
|||||||
guard let model = model as? LinkModel else { return }
|
guard let model = model as? LinkModel else { return }
|
||||||
|
|
||||||
setTitle(model.title, for: .normal)
|
setTitle(model.title, for: .normal)
|
||||||
setTitleColor(model.textColor.uiColor, for: .normal)
|
setTitleColor(model.enabledColor.uiColor, for: .normal)
|
||||||
setTitleColor(model.disabledColor.uiColor, for: .disabled)
|
setTitleColor(model.disabledColor.uiColor, for: .disabled)
|
||||||
isEnabled = model.enabled
|
isEnabled = model.enabled
|
||||||
set(with: model.action, delegateObject: delegateObject, additionalData: additionalData)
|
set(with: model.action, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
|
|||||||
@ -21,7 +21,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
|
|||||||
public var title: String
|
public var title: String
|
||||||
public var action: ActionModelProtocol
|
public var action: ActionModelProtocol
|
||||||
public var enabled = true
|
public var enabled = true
|
||||||
public var textColor = Color(uiColor: .mvmBlack)
|
public var enabledColor = Color(uiColor: .mvmBlack)
|
||||||
public var disabledColor = Color(uiColor: .mvmCoolGray6)
|
public var disabledColor = Color(uiColor: .mvmCoolGray6)
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -43,7 +43,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
|
|||||||
case title
|
case title
|
||||||
case action
|
case action
|
||||||
case enabled
|
case enabled
|
||||||
case textColor
|
case enabledColor
|
||||||
case disabledColor
|
case disabledColor
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,8 +60,8 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
|
|||||||
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
||||||
self.enabled = enabled
|
self.enabled = enabled
|
||||||
}
|
}
|
||||||
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor) {
|
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) {
|
||||||
textColor = color
|
enabledColor = color
|
||||||
}
|
}
|
||||||
|
|
||||||
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) {
|
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) {
|
||||||
@ -76,7 +76,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol {
|
|||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
try container.encodeModel(action, forKey: .action)
|
try container.encodeModel(action, forKey: .action)
|
||||||
try container.encode(enabled, forKey: .enabled)
|
try container.encode(enabled, forKey: .enabled)
|
||||||
try container.encode(textColor, forKey: .textColor)
|
try container.encode(enabledColor, forKey: .enabledColor)
|
||||||
try container.encode(disabledColor, forKey: .disabledColor)
|
try container.encode(disabledColor, forKey: .disabledColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,13 +19,14 @@ import UIKit
|
|||||||
widthConstraint?.constant = diameter
|
widthConstraint?.constant = diameter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override var isSelected: Bool {
|
public override var isSelected: Bool {
|
||||||
didSet {
|
didSet {
|
||||||
radioModel?.state = isSelected
|
radioModel?.state = isSelected
|
||||||
|
updateAccessibilityLabel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public var enabledColor: UIColor = .mvmBlack
|
public var enabledColor: UIColor = .mvmBlack
|
||||||
public var disabledColor: UIColor = .mvmCoolGray3
|
public var disabledColor: UIColor = .mvmCoolGray3
|
||||||
public var delegateObject: MVMCoreUIDelegateObject?
|
public var delegateObject: MVMCoreUIDelegateObject?
|
||||||
@ -39,12 +40,12 @@ import UIKit
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
lazy public var radioButtonSelectionHelper: RadioButtonSelectionHelper? = {
|
lazy public var radioButtonSelectionHelper: RadioButtonSelectionHelper? = {
|
||||||
if let radioGroupName = radioGroupName,
|
|
||||||
let radioButtonModel = delegateObject?.formHolderDelegate?.formValidator?.radioButtonsModelByGroup[radioGroupName] {
|
guard let radioGroupName = radioGroupName,
|
||||||
return radioButtonModel
|
let radioButtonModel = delegateObject?.formHolderDelegate?.formValidator?.radioButtonsModelByGroup[radioGroupName]
|
||||||
} else {
|
else { return nil }
|
||||||
return nil
|
|
||||||
}
|
return radioButtonModel
|
||||||
}()
|
}()
|
||||||
|
|
||||||
public override var isEnabled: Bool {
|
public override var isEnabled: Bool {
|
||||||
@ -90,6 +91,9 @@ import UIKit
|
|||||||
|
|
||||||
/// The action performed when tapped.
|
/// The action performed when tapped.
|
||||||
func tapAction() {
|
func tapAction() {
|
||||||
|
if !isEnabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
if let radioButtonModel = radioButtonSelectionHelper {
|
if let radioButtonModel = radioButtonSelectionHelper {
|
||||||
radioButtonModel.selected(self)
|
radioButtonModel.selected(self)
|
||||||
} else {
|
} else {
|
||||||
@ -115,6 +119,18 @@ import UIKit
|
|||||||
return radioModel?.fieldValue
|
return radioModel?.fieldValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Methods
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
/// Adjust accessibility label based on state of RadioButton.
|
||||||
|
func updateAccessibilityLabel() {
|
||||||
|
|
||||||
|
if let state = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "radio_selected_state" : "radio_not_selected_state") {
|
||||||
|
accessibilityLabel = String(format: MVMCoreUIUtility.hardcodedString(withKey: "radio_desc_state") ?? "%@%@", "", state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - MVMViewProtocol
|
// MARK: - MVMViewProtocol
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -133,14 +149,15 @@ import UIKit
|
|||||||
isAccessibilityElement = true
|
isAccessibilityElement = true
|
||||||
accessibilityTraits = .button
|
accessibilityTraits = .button
|
||||||
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "radio_action_hint")
|
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "radio_action_hint")
|
||||||
|
updateAccessibilityLabel()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
self.delegateObject = delegateObject
|
||||||
|
|
||||||
guard let model = model as? RadioButtonModel else { return }
|
guard let model = model as? RadioButtonModel else { return }
|
||||||
|
|
||||||
self.delegateObject = delegateObject
|
|
||||||
isSelected = model.state
|
isSelected = model.state
|
||||||
isEnabled = model.enabled
|
isEnabled = model.enabled
|
||||||
RadioButtonSelectionHelper.setupForRadioButtonGroup(model, self, delegateObject: delegateObject)
|
RadioButtonSelectionHelper.setupForRadioButtonGroup(model, self, delegateObject: delegateObject)
|
||||||
|
|||||||
166
MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatch.swift
Normal file
166
MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatch.swift
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
//
|
||||||
|
// RadioSwatch.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 01/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
open class RadioSwatch: Control {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
public let bottomText = Label.createLabelRegularMicro(true)
|
||||||
|
|
||||||
|
private var circleLayer: CAShapeLayer?
|
||||||
|
private var selectedLayer: CALayer?
|
||||||
|
private var strikeLayer: CALayer?
|
||||||
|
private var maskLayer: CALayer?
|
||||||
|
|
||||||
|
public var radioSwatchModel: RadioSwatchModel? {
|
||||||
|
return model as? RadioSwatchModel
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Lifecycle
|
||||||
|
//--------------------------------------------------
|
||||||
|
open override func updateView(_ size: CGFloat) {
|
||||||
|
super.updateView(size)
|
||||||
|
bottomText.updateView(size)
|
||||||
|
layer.setNeedsDisplay()
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
|
||||||
|
addSubview(bottomText)
|
||||||
|
bottomText.textAlignment = .center
|
||||||
|
NSLayoutConstraint.constraintPinSubview(bottomText, pinTop: true, topConstant: 38, pinBottom: true, bottomConstant: 0, pinLeft: true, leftConstant: 0, pinRight: true, rightConstant: 0)
|
||||||
|
addTarget(self, action: #selector(selectSwatch), for: .touchUpInside)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
guard let model = model as? RadioSwatchModel else { return }
|
||||||
|
isSelected = model.selected
|
||||||
|
isEnabled = model.enabled
|
||||||
|
bottomText.text = model.text
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func reset() {
|
||||||
|
super.reset()
|
||||||
|
isSelected = false
|
||||||
|
isEnabled = true
|
||||||
|
bottomText.text = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
// MARK: - State Handling
|
||||||
|
//------------------------------------------------------
|
||||||
|
open override func draw(_ layer: CALayer, in ctx: CGContext) {
|
||||||
|
//Draw the swatch
|
||||||
|
circleLayer?.removeFromSuperlayer()
|
||||||
|
let circle = getCircle(color: isSelected ? .mvmBlack : .mvmCoolGray6, thickness: 1)
|
||||||
|
layer.addSublayer(circle)
|
||||||
|
circleLayer = circle
|
||||||
|
|
||||||
|
//Draw the strikethrough
|
||||||
|
strikeLayer?.removeFromSuperlayer()
|
||||||
|
if radioSwatchModel?.strikethrough ?? false {
|
||||||
|
let line = getStrikeThrough(color: isSelected ? .mvmBlack : .mvmCoolGray6, thickness: 1)
|
||||||
|
layer.addSublayer(line)
|
||||||
|
strikeLayer = line
|
||||||
|
}
|
||||||
|
|
||||||
|
//Draw the selected layer
|
||||||
|
selectedLayer?.removeFromSuperlayer()
|
||||||
|
if isSelected {
|
||||||
|
let outerCircle = getSelectedLayer(color: isSelected ? .mvmBlack : .mvmCoolGray6, thickness: 1)
|
||||||
|
layer.addSublayer(outerCircle)
|
||||||
|
selectedLayer = outerCircle
|
||||||
|
bottomText.isHidden = false
|
||||||
|
} else {
|
||||||
|
bottomText.isHidden = true
|
||||||
|
}
|
||||||
|
|
||||||
|
//Handle Mask
|
||||||
|
maskLayer?.removeFromSuperlayer()
|
||||||
|
if !isEnabled {
|
||||||
|
let mask = getMaskLayer()
|
||||||
|
layer.mask = mask
|
||||||
|
maskLayer = mask
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
// Accounts for any size changes
|
||||||
|
layer.setNeedsDisplay()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc open func selectSwatch() {
|
||||||
|
guard isEnabled else { return }
|
||||||
|
isSelected = true
|
||||||
|
radioSwatchModel?.selected = isSelected
|
||||||
|
layer.setNeedsDisplay()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc open func deselectSwatch() {
|
||||||
|
isSelected = false
|
||||||
|
radioSwatchModel?.selected = isSelected
|
||||||
|
layer.setNeedsDisplay()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCircle(color: UIColor, thickness: CGFloat) -> CAShapeLayer {
|
||||||
|
let circle = CAShapeLayer()
|
||||||
|
circle.name = "innercircle"
|
||||||
|
circle.fillColor = radioSwatchModel?.color.cgColor ?? UIColor.blue.cgColor
|
||||||
|
circle.opacity = 1.0
|
||||||
|
circle.lineWidth = thickness
|
||||||
|
circle.strokeColor = color.cgColor
|
||||||
|
|
||||||
|
let circlePath = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30))
|
||||||
|
circle.path = circlePath.cgPath
|
||||||
|
return circle
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStrikeThrough(color: UIColor, thickness: CGFloat) -> CAShapeLayer {
|
||||||
|
let strikeThrough = CAShapeLayer()
|
||||||
|
strikeThrough.name = "strikethrough"
|
||||||
|
strikeThrough.fillColor = nil
|
||||||
|
strikeThrough.opacity = 1.0
|
||||||
|
strikeThrough.lineWidth = thickness
|
||||||
|
strikeThrough.strokeColor = color.cgColor
|
||||||
|
|
||||||
|
let linePath = UIBezierPath()
|
||||||
|
linePath.move(to: CGPoint(x: 12, y: 31))
|
||||||
|
linePath.addLine(to: CGPoint(x: 42, y: 1))
|
||||||
|
strikeThrough.path = linePath.cgPath
|
||||||
|
return strikeThrough
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSelectedLayer(color: UIColor, thickness: CGFloat) -> CAShapeLayer {
|
||||||
|
circleLayer?.path = UIBezierPath(ovalIn: CGRect(x: 15, y: 4, width: 24, height: 24)).cgPath
|
||||||
|
let circle = CAShapeLayer()
|
||||||
|
circle.name = "outercircle"
|
||||||
|
circle.fillColor = UIColor.clear.cgColor
|
||||||
|
circle.opacity = 1.0
|
||||||
|
circle.lineWidth = thickness
|
||||||
|
circle.strokeColor = color.cgColor
|
||||||
|
|
||||||
|
let circlePath = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30))
|
||||||
|
circle.path = circlePath.cgPath
|
||||||
|
return circle
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMaskLayer() -> CALayer {
|
||||||
|
let mask = CALayer()
|
||||||
|
mask.backgroundColor = UIColor.white.cgColor
|
||||||
|
mask.opacity = 0.3
|
||||||
|
mask.frame = bounds
|
||||||
|
return mask
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// RadioSwatchCollectionViewCell.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 13/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
open class RadioSwatchCollectionViewCell: CollectionViewCell {
|
||||||
|
public let radioSwatch = RadioSwatch()
|
||||||
|
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
addMolecule(radioSwatch)
|
||||||
|
MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
guard let model = model as? RadioSwatchModel else { return }
|
||||||
|
radioSwatch.set(with: model, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
}
|
||||||
64
MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift
Normal file
64
MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// RadioSwatchModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 4/17/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers public class RadioSwatchModel: MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "radioSwatch"
|
||||||
|
public var backgroundColor: Color?
|
||||||
|
public var color: Color = Color(uiColor: .mvmBlue)
|
||||||
|
public var text: String?
|
||||||
|
public var selected: Bool = false
|
||||||
|
public var enabled: Bool = true
|
||||||
|
public var strikethrough: Bool = false
|
||||||
|
public var fieldValue: String?
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case backgroundColor
|
||||||
|
case color
|
||||||
|
case text
|
||||||
|
case selected
|
||||||
|
case enabled
|
||||||
|
case strikethrough
|
||||||
|
case fieldValue
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
|
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) {
|
||||||
|
self.color = color
|
||||||
|
}
|
||||||
|
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
||||||
|
if let selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) {
|
||||||
|
self.selected = selected
|
||||||
|
}
|
||||||
|
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
||||||
|
self.enabled = enabled
|
||||||
|
}
|
||||||
|
if let strikethrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) {
|
||||||
|
self.strikethrough = strikethrough
|
||||||
|
}
|
||||||
|
fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
|
try container.encode(color, forKey: .color)
|
||||||
|
try container.encodeIfPresent(text, forKey: .text)
|
||||||
|
try container.encode(selected, forKey: .selected)
|
||||||
|
try container.encode(enabled, forKey: .enabled)
|
||||||
|
try container.encode(strikethrough, forKey: .strikethrough)
|
||||||
|
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
152
MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift
Normal file
152
MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
//
|
||||||
|
// RadioSwatches.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 01/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class RadioSwatches: View {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
public var collectionView: CollectionView!
|
||||||
|
public var swatches: [RadioSwatchModel]?
|
||||||
|
private var size: CGFloat?
|
||||||
|
private var delegateObject: MVMCoreUIDelegateObject?
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
// MARK: - Constraints
|
||||||
|
//------------------------------------------------------
|
||||||
|
public var collectionViewHeight: NSLayoutConstraint?
|
||||||
|
private let cellSize: CGFloat = 54.0
|
||||||
|
private let itemSpacing: CGFloat = 8.0
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Lifecycle
|
||||||
|
//--------------------------------------------------
|
||||||
|
open override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
// Accounts for any collection size changes
|
||||||
|
setHeight()
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.collectionView.collectionViewLayout.invalidateLayout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
collectionView = createCollectionView()
|
||||||
|
addSubview(collectionView)
|
||||||
|
NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView)
|
||||||
|
collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 100)
|
||||||
|
collectionViewHeight?.isActive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc override open func updateView(_ size: CGFloat) {
|
||||||
|
super.updateView(size)
|
||||||
|
self.size = size
|
||||||
|
collectionView.updateView(size)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
self.delegateObject = delegateObject
|
||||||
|
|
||||||
|
guard let radioSwatchesModel = model as? RadioSwatchesModel else { return }
|
||||||
|
swatches = radioSwatchesModel.swatches
|
||||||
|
FormValidator.setupValidation(for: radioSwatchesModel, delegate: delegateObject?.formHolderDelegate)
|
||||||
|
collectionView.reloadData()
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
// MARK: - Methods
|
||||||
|
//------------------------------------------------------
|
||||||
|
/// Creates the collection view.
|
||||||
|
open func createCollectionView() -> CollectionView {
|
||||||
|
let collection = CollectionView(frame: .zero, collectionViewLayout: createCollectionViewLayout())
|
||||||
|
collection.dataSource = self
|
||||||
|
collection.delegate = self
|
||||||
|
collection.register(RadioSwatchCollectionViewCell.self, forCellWithReuseIdentifier: "RadioSwatchCollectionViewCell")
|
||||||
|
return collection
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates the layout for the collection.
|
||||||
|
open func createCollectionViewLayout() -> UICollectionViewLayout {
|
||||||
|
let layout = UICollectionViewFlowLayout()
|
||||||
|
layout.scrollDirection = .vertical
|
||||||
|
layout.minimumLineSpacing = itemSpacing
|
||||||
|
layout.minimumInteritemSpacing = itemSpacing
|
||||||
|
return layout
|
||||||
|
}
|
||||||
|
|
||||||
|
open func setHeight() {
|
||||||
|
guard let swatches = swatches, swatches.count > 0 else {
|
||||||
|
collectionViewHeight?.constant = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Calculate the height
|
||||||
|
let swatchesInRow = floor(CGFloat(collectionView.bounds.width/(cellSize + itemSpacing)))
|
||||||
|
let numberOfRows = ceil(CGFloat(swatches.count)/swatchesInRow)
|
||||||
|
let height = (numberOfRows * cellSize) + (itemSpacing * (numberOfRows-1))
|
||||||
|
|
||||||
|
if let oldHeight = collectionViewHeight?.constant,
|
||||||
|
height != oldHeight {
|
||||||
|
// Notify delegate of height change, called async to avoid various race conditions caused while happening while laying out initially.
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
collectionViewHeight?.constant = CGFloat(height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
// MARK: - Delegate methods
|
||||||
|
//------------------------------------------------------
|
||||||
|
extension RadioSwatches: UICollectionViewDelegateFlowLayout {
|
||||||
|
open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
|
||||||
|
return CGSize(width: cellSize, height: cellSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension RadioSwatches: UICollectionViewDataSource {
|
||||||
|
open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
|
return swatches?.count ?? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
|
guard let molecule = swatches?[indexPath.row], let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioSwatchCollectionViewCell", for: indexPath) as? RadioSwatchCollectionViewCell else {
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
cell.reset()
|
||||||
|
cell.radioSwatch.isUserInteractionEnabled = false
|
||||||
|
cell.set(with: molecule, delegateObject, nil)
|
||||||
|
cell.updateView(size ?? collectionView.bounds.width)
|
||||||
|
if molecule.selected {
|
||||||
|
collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically)
|
||||||
|
}
|
||||||
|
cell.layoutIfNeeded()
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension RadioSwatches: UICollectionViewDelegate {
|
||||||
|
open func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
|
||||||
|
guard let molecule = swatches?[indexPath.row] else { return false }
|
||||||
|
return molecule.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
|
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchCollectionViewCell else { return }
|
||||||
|
cell.radioSwatch.selectSwatch()
|
||||||
|
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||||
|
}
|
||||||
|
|
||||||
|
open func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
|
||||||
|
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchCollectionViewCell else { return }
|
||||||
|
cell.radioSwatch.deselectSwatch()
|
||||||
|
}
|
||||||
|
}
|
||||||
54
MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift
Normal file
54
MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// RadioSwatchesModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 31/03/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers public class RadioSwatchesModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||||
|
public static var identifier: String = "radioSwatches"
|
||||||
|
public var backgroundColor: Color?
|
||||||
|
public var swatches: [RadioSwatchModel]
|
||||||
|
public var fieldKey: String?
|
||||||
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
|
public var baseValue: AnyHashable?
|
||||||
|
|
||||||
|
/// Returns the fieldValue of the selected swatch, otherwise the text of selected swatch.
|
||||||
|
public func formFieldValue() -> AnyHashable? {
|
||||||
|
let selectedSwatch = swatches.first { (swatch) -> Bool in
|
||||||
|
return swatch.selected
|
||||||
|
}
|
||||||
|
return selectedSwatch?.fieldValue ?? selectedSwatch?.text
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case backgroundColor
|
||||||
|
case swatches
|
||||||
|
case fieldKey
|
||||||
|
case groupName
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
|
swatches = try typeContainer.decode([RadioSwatchModel].self, forKey: .swatches)
|
||||||
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
|
self.groupName = groupName
|
||||||
|
}
|
||||||
|
baseValue = formFieldValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
|
try container.encode(swatches, forKey: .swatches)
|
||||||
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
|
try container.encode(groupName, forKey: .groupName)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -69,7 +69,7 @@ import UIKit
|
|||||||
textFieldTrailingConstraint = dropDownCaretView.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 6)
|
textFieldTrailingConstraint = dropDownCaretView.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 6)
|
||||||
textFieldTrailingConstraint?.isActive = true
|
textFieldTrailingConstraint?.isActive = true
|
||||||
|
|
||||||
container.trailingAnchor.constraint(equalTo: dropDownCaretView.trailingAnchor, constant: 16).isActive = true
|
container.trailingAnchor.constraint(equalTo: dropDownCaretView.trailingAnchor, constant: Padding.Four).isActive = true
|
||||||
dropDownCaretView.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true
|
dropDownCaretView.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,10 +31,9 @@ import UIKit
|
|||||||
return formatter
|
return formatter
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
/// Update the property value to alter the format of how the date is presented.
|
||||||
public var dateFormat: String = "MMM d, y" {
|
public var dateFormat: String = "MMM d, y" {
|
||||||
didSet {
|
didSet { dateFormatter.dateFormat = dateFormat }
|
||||||
dateFormatter.dateFormat = dateFormat
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -69,10 +68,10 @@ import UIKit
|
|||||||
public override func setupFieldContainerContent(_ container: UIView) {
|
public override func setupFieldContainerContent(_ container: UIView) {
|
||||||
super.setupFieldContainerContent(container)
|
super.setupFieldContainerContent(container)
|
||||||
|
|
||||||
datePicker = MVMCoreUICommonViewsUtility.addDatePicker(to: textField)
|
datePicker = UIDatePicker.addDatePicker(to: textField)
|
||||||
datePicker?.addTarget(self, action: #selector(pickerValueChanged), for: .valueChanged)
|
datePicker?.addTarget(self, action: #selector(pickerValueChanged), for: .valueChanged)
|
||||||
datePicker?.timeZone = NSTimeZone.system
|
datePicker?.timeZone = NSTimeZone.system
|
||||||
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: self)
|
UIToolbar.addDismissToolbar(to: textField, delegate: self, action: #selector(dismissFieldInput))
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public func setDatePickerDuration(from startDate: Date?, to endDate: Date?, showStartDate: Bool = true) {
|
@objc public func setDatePickerDuration(from startDate: Date?, to endDate: Date?, showStartDate: Bool = true) {
|
||||||
@ -104,7 +103,7 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc override func dismissFieldInput(_ sender: Any?) {
|
@objc public override func dismissFieldInput(_ sender: Any?) {
|
||||||
|
|
||||||
setTextWith(date: datePicker?.date)
|
setTextWith(date: datePicker?.date)
|
||||||
super.dismissFieldInput(sender)
|
super.dismissFieldInput(sender)
|
||||||
|
|||||||
@ -22,24 +22,25 @@
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
|
||||||
case dateFormat
|
case dateFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Codec
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
dateFormat = try typeContainer.decodeIfPresent(String.self, forKey: .dateFormat) ?? "MMM d, y"
|
|
||||||
|
if let dateFormat = try typeContainer.decodeIfPresent(String.self, forKey: .dateFormat) {
|
||||||
|
self.dateFormat = dateFormat
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
|
||||||
try container.encode(dateFormat, forKey: .dateFormat)
|
try container.encode(dateFormat, forKey: .dateFormat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -211,7 +211,9 @@ import UIKit
|
|||||||
|
|
||||||
let digitBox = DigitBox()
|
let digitBox = DigitBox()
|
||||||
digitBox.isAccessibilityElement = true
|
digitBox.isAccessibilityElement = true
|
||||||
digitBox.digitField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: self)
|
let observingDelegate = delegateObject?.observingTextFieldDelegate ?? self
|
||||||
|
digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate,
|
||||||
|
action: #selector(observingDelegate.dismissFieldInput))
|
||||||
digitBox.digitField.delegate = self
|
digitBox.digitField.delegate = self
|
||||||
digitBox.digitBoxDelegate = self
|
digitBox.digitBoxDelegate = self
|
||||||
return digitBox
|
return digitBox
|
||||||
@ -246,15 +248,6 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public override func defaultValidationBlock() {
|
|
||||||
|
|
||||||
validationBlock = { enteredValue in
|
|
||||||
guard let enteredValue = enteredValue else { return false }
|
|
||||||
|
|
||||||
return enteredValue.count > 0 && enteredValue.count == self.digitBoxes.count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func selectPreviousDigitField(_ currentTextField: UITextField?, clear: Bool) {
|
@objc public func selectPreviousDigitField(_ currentTextField: UITextField?, clear: Bool) {
|
||||||
|
|
||||||
var selectPreviousField = false
|
var selectPreviousField = false
|
||||||
@ -322,7 +315,7 @@ import UIKit
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc override func dismissFieldInput(_ sender: Any?) {
|
@objc public override func dismissFieldInput(_ sender: Any?) {
|
||||||
|
|
||||||
digitBoxes.forEach {
|
digitBoxes.forEach {
|
||||||
if $0.isSelected {
|
if $0.isSelected {
|
||||||
@ -337,12 +330,18 @@ import UIKit
|
|||||||
guard let model = model as? DigitEntryFieldModel else { return }
|
guard let model = model as? DigitEntryFieldModel else { return }
|
||||||
|
|
||||||
numberOfDigits = model.digits
|
numberOfDigits = model.digits
|
||||||
setAsSecureTextEntry(model.secureEntry)
|
|
||||||
|
|
||||||
for digitBox in digitBoxes {
|
if let entryType = model.type {
|
||||||
digitBox.digitField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: delegateObject?.observingTextFieldDelegate ?? self)
|
setAsSecureTextEntry(entryType == .secure || entryType == .password)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let observingDelegate = delegateObject?.observingTextFieldDelegate ?? self
|
||||||
|
|
||||||
|
digitBoxes.forEach {
|
||||||
|
$0.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate,
|
||||||
|
action: #selector(observingDelegate.dismissFieldInput))
|
||||||
|
}
|
||||||
|
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,34 +17,31 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public var digits: Int = 4
|
public var digits: Int = 4
|
||||||
public var secureEntry: Bool = false
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
|
||||||
case digits
|
case digits
|
||||||
case secureEntry
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Codec
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
digits = try typeContainer.decodeIfPresent(Int.self, forKey: .digits) ?? 4
|
|
||||||
secureEntry = try typeContainer.decodeIfPresent(Bool.self, forKey: .secureEntry) ?? false
|
if let digits = try typeContainer.decodeIfPresent(Int.self, forKey: .digits) {
|
||||||
|
self.digits = digits
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
|
||||||
try container.encode(digits, forKey: .digits)
|
try container.encode(digits, forKey: .digits)
|
||||||
try container.encode(secureEntry, forKey: .secureEntry)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ import UIKit
|
|||||||
|
|
||||||
public private(set) var titleLabel: Label = {
|
public private(set) var titleLabel: Label = {
|
||||||
let label = Label()
|
let label = Label()
|
||||||
label.font = MFStyler.fontRegularMicro()
|
label.font = Styler.Font.RegularMicro.getFont()
|
||||||
label.textColor = .mvmBlack
|
label.textColor = .mvmBlack
|
||||||
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
return label
|
return label
|
||||||
@ -31,31 +31,23 @@ import UIKit
|
|||||||
/// Provides contextual information on the TextField.
|
/// Provides contextual information on the TextField.
|
||||||
public private(set) var feedbackLabel: Label = {
|
public private(set) var feedbackLabel: Label = {
|
||||||
let label = Label()
|
let label = Label()
|
||||||
label.font = MFStyler.fontRegularMicro()
|
label.font = Styler.Font.RegularMicro.getFont()
|
||||||
label.textColor = .mvmBlack
|
label.textColor = .mvmBlack
|
||||||
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Delegate
|
// MARK: - Delegate
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
weak var delegateObject: MVMCoreUIDelegateObject?
|
var delegateObject: MVMCoreUIDelegateObject?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Stored Properties
|
// MARK: - Stored Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public var isValid: Bool = false
|
public var isValid: Bool = false
|
||||||
public var errorMessage: String?
|
|
||||||
public var standardMessage: String? {
|
|
||||||
didSet {
|
|
||||||
if !showError {
|
|
||||||
feedback = standardMessage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Computed Properties
|
// MARK: - Computed Properties
|
||||||
@ -75,7 +67,7 @@ import UIKit
|
|||||||
public var showError: Bool {
|
public var showError: Bool {
|
||||||
get { return entryFieldContainer.showError }
|
get { return entryFieldContainer.showError }
|
||||||
set (error) {
|
set (error) {
|
||||||
self.feedback = error ? self.errorMessage : self.standardMessage
|
self.feedback = error ? entryFieldModel?.errorMessage : entryFieldModel?.feedback
|
||||||
self.entryFieldContainer.showError = error
|
self.entryFieldContainer.showError = error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,6 +113,10 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var entryFieldModel: EntryFieldModel? {
|
||||||
|
return model as? EntryFieldModel
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Constraints
|
// MARK: - Constraints
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -174,8 +170,6 @@ import UIKit
|
|||||||
@objc final public override func setupView() {
|
@objc final public override func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
|
|
||||||
guard subviews.isEmpty else { return }
|
|
||||||
|
|
||||||
isAccessibilityElement = false
|
isAccessibilityElement = false
|
||||||
setContentCompressionResistancePriority(.required, for: .vertical)
|
setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
accessibilityElements = [titleLabel, feedbackLabel]
|
accessibilityElements = [titleLabel, feedbackLabel]
|
||||||
@ -193,7 +187,7 @@ import UIKit
|
|||||||
entryFieldContainer.setContentCompressionResistancePriority(.required, for: .vertical)
|
entryFieldContainer.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
setupFieldContainerContent(entryFieldContainer)
|
setupFieldContainerContent(entryFieldContainer)
|
||||||
|
|
||||||
titleContainerDistance = entryFieldContainer.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 4)
|
titleContainerDistance = entryFieldContainer.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: Padding.One)
|
||||||
titleContainerDistance?.isActive = true
|
titleContainerDistance?.isActive = true
|
||||||
entryFieldContainerLeading = entryFieldContainer.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
|
entryFieldContainerLeading = entryFieldContainer.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
|
||||||
entryFieldContainerLeading?.isActive = true
|
entryFieldContainerLeading?.isActive = true
|
||||||
@ -202,7 +196,7 @@ import UIKit
|
|||||||
|
|
||||||
addSubview(feedbackLabel)
|
addSubview(feedbackLabel)
|
||||||
|
|
||||||
feedbackContainerDistance = feedbackLabel.topAnchor.constraint(equalTo: entryFieldContainer.bottomAnchor, constant: PaddingOne)
|
feedbackContainerDistance = feedbackLabel.topAnchor.constraint(equalTo: entryFieldContainer.bottomAnchor, constant: Padding.Two)
|
||||||
feedbackContainerDistance?.isActive = true
|
feedbackContainerDistance?.isActive = true
|
||||||
feedbackLabelLeading = feedbackLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
|
feedbackLabelLeading = feedbackLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
|
||||||
feedbackLabelLeading?.isActive = true
|
feedbackLabelLeading?.isActive = true
|
||||||
@ -217,11 +211,11 @@ import UIKit
|
|||||||
entryFieldContainer.refreshUI()
|
entryFieldContainer.refreshUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Method to override.
|
/**
|
||||||
/// Intended to add the interactive content (i.e. textField) to the entryFieldContainer.
|
Method to override.
|
||||||
@objc open func setupFieldContainerContent(_ container: UIView) {
|
Intended to add the interactive content (i.e. textField) to the entryFieldContainer.
|
||||||
// To be overridden by subclass.
|
*/
|
||||||
}
|
@objc open func setupFieldContainerContent(_ container: UIView) { }
|
||||||
|
|
||||||
@objc open override func updateView(_ size: CGFloat) {
|
@objc open override func updateView(_ size: CGFloat) {
|
||||||
super.updateView(size)
|
super.updateView(size)
|
||||||
@ -240,10 +234,11 @@ import UIKit
|
|||||||
|
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
isAccessibilityElement = false
|
isAccessibilityElement = false
|
||||||
titleLabel.font = MFStyler.fontRegularMicro()
|
titleLabel.font = Styler.Font.RegularMicro.getFont()
|
||||||
titleLabel.textColor = .mvmBlack
|
titleLabel.textColor = .mvmBlack
|
||||||
feedbackLabel.font = MFStyler.fontRegularMicro()
|
feedbackLabel.font = Styler.Font.RegularMicro.getFont()
|
||||||
feedbackLabel.textColor = .mvmBlack
|
feedbackLabel.textColor = .mvmBlack
|
||||||
|
feedbackLabel.text = nil
|
||||||
entryFieldContainer.reset()
|
entryFieldContainer.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,13 +252,12 @@ import UIKit
|
|||||||
|
|
||||||
title = model.title
|
title = model.title
|
||||||
feedback = model.feedback
|
feedback = model.feedback
|
||||||
errorMessage = model.errorMessage
|
isEnabled = model.enabled
|
||||||
isEnabled = model.isEnabled
|
|
||||||
|
|
||||||
if let isLocked = model.isLocked {
|
if let isLocked = model.locked {
|
||||||
self.isLocked = isLocked
|
self.isLocked = isLocked
|
||||||
|
|
||||||
} else if let isSelected = model.isSelected{
|
} else if let isSelected = model.selected {
|
||||||
self.isSelected = isSelected
|
self.isSelected = isSelected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol {
|
@objcMembers public class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, EnableableModelProtocol {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
@ -22,29 +22,22 @@ import Foundation
|
|||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var title: String?
|
public var title: String?
|
||||||
public var feedback: String?
|
public var feedback: String?
|
||||||
public var errorMessage: String = ""
|
public var errorMessage: String?
|
||||||
public var isEnabled: Bool = true
|
public var enabled: Bool = true
|
||||||
public var isLocked: Bool?
|
public var locked: Bool?
|
||||||
public var isSelected: Bool?
|
public var selected: Bool?
|
||||||
public var text: String?
|
public var text: String?
|
||||||
|
|
||||||
public var fieldKey: String?
|
public var fieldKey: String?
|
||||||
public var groupName: String = FormValidator.defaultGroupName
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
public var baseValue: AnyHashable?
|
public var baseValue: AnyHashable?
|
||||||
|
|
||||||
public var isValid: Bool? {
|
public var isValid: Bool? {
|
||||||
didSet {
|
didSet { updateUI?() }
|
||||||
updateUI?()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Temporary binding mechanism for the view to update on enable changes.
|
/// Temporary binding mechanism for the view to update on enable changes.
|
||||||
public var updateUI: (() -> Void)?
|
public var updateUI: (() -> ())?
|
||||||
|
|
||||||
public func setValidity(_ valid: Bool, rule: RulesProtocol) {
|
|
||||||
self.isValid = valid
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -52,23 +45,29 @@ import Foundation
|
|||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case backgroundColor
|
case backgroundColor
|
||||||
case title = "label"
|
case title
|
||||||
case isEnabled
|
case enabled
|
||||||
case feedback
|
case feedback
|
||||||
case errorMessage = "errorMsg"
|
case errorMessage
|
||||||
case isLocked
|
case locked
|
||||||
case isSelected
|
case selected
|
||||||
case isValid
|
|
||||||
case isRequired = "required"
|
|
||||||
case text
|
case text
|
||||||
case fieldKey
|
case fieldKey
|
||||||
case groupName
|
case groupName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Validation Methods
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public func formFieldValue() -> AnyHashable? {
|
public func formFieldValue() -> AnyHashable? {
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func setValidity(_ valid: Bool, rule: RulesProtocol) {
|
||||||
|
self.isValid = valid
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -78,18 +77,20 @@ import Foundation
|
|||||||
baseValue = text
|
baseValue = text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codec
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
|
title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
|
||||||
feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback)
|
feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback)
|
||||||
errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage) ?? ""
|
errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage)
|
||||||
isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEnabled) ?? true
|
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||||
isLocked = try typeContainer.decodeIfPresent(Bool.self, forKey: .isLocked)
|
locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked)
|
||||||
isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .isSelected)
|
selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected)
|
||||||
isValid = try typeContainer.decodeIfPresent(Bool.self, forKey: .isValid)
|
|
||||||
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
||||||
|
|
||||||
baseValue = text
|
baseValue = text
|
||||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
@ -103,13 +104,12 @@ import Foundation
|
|||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
try container.encodeIfPresent(title, forKey: .title)
|
try container.encodeIfPresent(title, forKey: .title)
|
||||||
try container.encodeIfPresent(feedback, forKey: .feedback)
|
try container.encodeIfPresent(feedback, forKey: .feedback)
|
||||||
try container.encode(errorMessage, forKey: .errorMessage)
|
|
||||||
try container.encode(isEnabled, forKey: .isEnabled)
|
|
||||||
try container.encode(isLocked, forKey: .isLocked)
|
|
||||||
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(text, forKey: .text)
|
||||||
|
try container.encodeIfPresent(locked, forKey: .locked)
|
||||||
|
try container.encodeIfPresent(selected, forKey: .selected)
|
||||||
|
try container.encodeIfPresent(errorMessage, forKey: .errorMessage)
|
||||||
|
try container.encode(enabled, forKey: .enabled)
|
||||||
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
try container.encodeIfPresent(groupName, forKey: .groupName)
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
public typealias TextFieldAndPickerDelegate = (UITextFieldDelegate & UIPickerViewDelegate & UIPickerViewDataSource)
|
||||||
|
|
||||||
|
|
||||||
open class ItemDropdownEntryField: BaseDropdownEntryField {
|
open class ItemDropdownEntryField: BaseDropdownEntryField {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -62,7 +64,7 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
|||||||
@objc open override func setupFieldContainerContent(_ container: UIView) {
|
@objc open override func setupFieldContainerContent(_ container: UIView) {
|
||||||
super.setupFieldContainerContent(container)
|
super.setupFieldContainerContent(container)
|
||||||
|
|
||||||
pickerView = MVMCoreUICommonViewsUtility.addPicker(to: textField, delegate: self)
|
pickerView = UIPickerView.addPicker(to: textField, delegate: self, dismissAction: #selector(dismissFieldInput))
|
||||||
textField.hideBlinkingCaret = true
|
textField.hideBlinkingCaret = true
|
||||||
textField.autocorrectionType = .no
|
textField.autocorrectionType = .no
|
||||||
uiTextFieldDelegate = self
|
uiTextFieldDelegate = self
|
||||||
|
|||||||
@ -17,17 +17,21 @@
|
|||||||
|
|
||||||
public var options: [String] = []
|
public var options: [String] = []
|
||||||
public var selectedIndex: Int = 0
|
public var selectedIndex: Int = 0
|
||||||
|
|
||||||
|
public override func formFieldValue() -> AnyHashable? {
|
||||||
|
guard !options.isEmpty else { return nil }
|
||||||
|
return options[selectedIndex]
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
|
||||||
case options
|
case options
|
||||||
case selectedIndex
|
case selectedIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -35,14 +39,17 @@
|
|||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
|
||||||
options = try typeContainer.decode([String].self, forKey: .options)
|
options = try typeContainer.decode([String].self, forKey: .options)
|
||||||
selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) ?? 0
|
|
||||||
|
if let selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) {
|
||||||
|
self.selectedIndex = selectedIndex
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
|
||||||
try container.encode(options, forKey: .options)
|
try container.encode(options, forKey: .options)
|
||||||
try container.encode(options, forKey: .selectedIndex)
|
try container.encode(options, forKey: .selectedIndex)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,18 @@ import MVMCore
|
|||||||
set { text = MVMCoreUIUtility.formatMdn(newValue) }
|
set { text = MVMCoreUIUtility.formatMdn(newValue) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Toggles selected or original (unselected) UI.
|
||||||
|
public override var isSelected: Bool {
|
||||||
|
get { return entryFieldContainer.isSelected }
|
||||||
|
set (selected) {
|
||||||
|
if selected && showError {
|
||||||
|
showError = false
|
||||||
|
}
|
||||||
|
|
||||||
|
super.isSelected = selected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -77,11 +89,14 @@ import MVMCore
|
|||||||
super.setupFieldContainerContent(container)
|
super.setupFieldContainerContent(container)
|
||||||
|
|
||||||
textField.keyboardType = .numberPad
|
textField.keyboardType = .numberPad
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func setupTextFieldToolbar() {
|
||||||
|
|
||||||
let toolbar = MVMCoreUICommonViewsUtility.makeEmptyToolbar()
|
let toolbar = UIToolbar.createEmptyToolbar()
|
||||||
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
||||||
let contacts = UIBarButtonItem(title: MVMCoreUIUtility.hardcodedString(withKey: "textfield_contacts_barbutton"), style: .plain, target: self, action: #selector(getContacts(_:)))
|
let contacts = UIBarButtonItem(title: MVMCoreUIUtility.hardcodedString(withKey: "textfield_contacts_barbutton"), style: .plain, target: self, action: #selector(getContacts))
|
||||||
let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissFieldInput(_:)))
|
let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissFieldInput))
|
||||||
toolbar.items = [contacts, space, dismissButton]
|
toolbar.items = [contacts, space, dismissButton]
|
||||||
textField.inputAccessoryView = toolbar
|
textField.inputAccessoryView = toolbar
|
||||||
}
|
}
|
||||||
@ -107,18 +122,18 @@ import MVMCore
|
|||||||
isValid = true
|
isValid = true
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
let isValid = hasValidMDN()
|
isValid = hasValidMDN()
|
||||||
|
|
||||||
if isValid {
|
if self.isValid {
|
||||||
showError = false
|
showError = false
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
|
entryFieldModel?.errorMessage = entryFieldModel?.errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
|
||||||
showError = true
|
showError = true
|
||||||
UIAccessibility.post(notification: .layoutChanged, argument: textField)
|
UIAccessibility.post(notification: .layoutChanged, argument: textField)
|
||||||
}
|
}
|
||||||
|
|
||||||
return isValid
|
return isValid
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +211,7 @@ import MVMCore
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
|
@objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
|
||||||
|
|
||||||
return proprietorTextDelegate?.textFieldShouldBeginEditing?(textField) ?? true
|
return proprietorTextDelegate?.textFieldShouldBeginEditing?(textField) ?? true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import UIKit
|
|||||||
/// Called when the entered text becomes invalid based on the validation block
|
/// Called when the entered text becomes invalid based on the validation block
|
||||||
@objc optional func isInvalid(textfield: TextEntryField?)
|
@objc optional func isInvalid(textfield: TextEntryField?)
|
||||||
/// Dismisses the keyboard.
|
/// Dismisses the keyboard.
|
||||||
@objc optional func dismissFieldInput(sender: Any?)
|
@objc optional func dismissFieldInput(_ sender: Any?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ import UIKit
|
|||||||
let textField = TextField()
|
let textField = TextField()
|
||||||
textField.isAccessibilityElement = true
|
textField.isAccessibilityElement = true
|
||||||
textField.setContentCompressionResistancePriority(.required, for: .vertical)
|
textField.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
textField.font = MFStyler.fontRegularBodyLarge()
|
textField.font = Styler.Font.RegularBodyLarge.getFont()
|
||||||
textField.textColor = .mvmBlack
|
textField.textColor = .mvmBlack
|
||||||
textField.smartQuotesType = .no
|
textField.smartQuotesType = .no
|
||||||
textField.smartDashesType = .no
|
textField.smartDashesType = .no
|
||||||
@ -36,13 +36,19 @@ import UIKit
|
|||||||
return textField
|
return textField
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
public lazy var errorImage: UIImageView = {
|
||||||
|
let image = MVMCoreUIUtility.imageNamed("alert_standard")
|
||||||
|
let imageView = UIImageView(image: image)
|
||||||
|
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
imageView.heightAnchor.constraint(equalToConstant: 20).isActive = true
|
||||||
|
imageView.widthAnchor.constraint(equalToConstant: 20).isActive = true
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Stored Properties
|
// MARK: - Stored Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
/// Set enabled and disabled colors to be utilized when setting this texfield's isEnabled property.
|
|
||||||
public var textColor: (enabled: UIColor?, disabled: UIColor?) = (.mvmBlack, .mvmCoolGray3)
|
|
||||||
|
|
||||||
private var observingForChange: Bool = false
|
private var observingForChange: Bool = false
|
||||||
|
|
||||||
/// Validate on each entry in the textField. Default: true
|
/// Validate on each entry in the textField. Default: true
|
||||||
@ -54,7 +60,7 @@ import UIKit
|
|||||||
public var textEntryFieldModel: TextEntryFieldModel? {
|
public var textEntryFieldModel: TextEntryFieldModel? {
|
||||||
return model as? TextEntryFieldModel
|
return model as? TextEntryFieldModel
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Computed Properties
|
// MARK: - Computed Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -68,7 +74,7 @@ import UIKit
|
|||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
self.textField.isEnabled = enabled
|
self.textField.isEnabled = enabled
|
||||||
self.textField.textColor = enabled ? self.textColor.enabled : self.textColor.disabled
|
self.textField.textColor = enabled ? self.textEntryFieldModel?.enabledTextColor.uiColor : self.textEntryFieldModel?.disabledTextColor.uiColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,11 +84,15 @@ import UIKit
|
|||||||
set (error) {
|
set (error) {
|
||||||
|
|
||||||
if error {
|
if error {
|
||||||
textField.accessibilityValue = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textfield_error_message") ?? "", textField.text ?? "", errorMessage ?? "")
|
textField.accessibilityValue = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textfield_error_message") ?? "", textField.text ?? "", entryFieldModel?.errorMessage ?? "")
|
||||||
} else {
|
} else {
|
||||||
textField.accessibilityValue = nil
|
textField.accessibilityValue = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if textField.isSecureTextEntry {
|
||||||
|
showErrorView(error)
|
||||||
|
}
|
||||||
|
|
||||||
super.showError = error
|
super.showError = error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,12 +112,6 @@ import UIKit
|
|||||||
set { textField.placeholder = newValue }
|
set { textField.placeholder = newValue }
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Property Observers
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
public var validationBlock: ((_ value: String?) -> Bool)?
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Delegate Properties
|
// MARK: - Delegate Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -169,21 +173,21 @@ import UIKit
|
|||||||
|
|
||||||
@objc open override func setupFieldContainerContent(_ container: UIView) {
|
@objc open override func setupFieldContainerContent(_ container: UIView) {
|
||||||
|
|
||||||
textField.font = MFStyler.fontRegularBodyLarge()
|
textField.font = Styler.Font.RegularBodyLarge.getFont()
|
||||||
container.addSubview(textField)
|
container.addSubview(textField)
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
textField.heightAnchor.constraint(equalToConstant: 24),
|
textField.heightAnchor.constraint(equalToConstant: Padding.Five),
|
||||||
textField.topAnchor.constraint(equalTo: container.topAnchor, constant: 12),
|
textField.topAnchor.constraint(equalTo: container.topAnchor, constant: Padding.Three),
|
||||||
textField.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 16),
|
textField.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: Padding.Three),
|
||||||
container.bottomAnchor.constraint(equalTo: textField.bottomAnchor, constant: 12)
|
container.bottomAnchor.constraint(equalTo: textField.bottomAnchor, constant: Padding.Three)
|
||||||
])
|
])
|
||||||
|
|
||||||
textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 16)
|
textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Three)
|
||||||
textFieldTrailingConstraint?.isActive = true
|
textFieldTrailingConstraint?.isActive = true
|
||||||
|
|
||||||
textField.addTarget(self, action: #selector(startEditing), for: .editingDidBegin)
|
textField.addTarget(self, action: #selector(startEditing), for: .editingDidBegin)
|
||||||
textField.addTarget(self, action: #selector(dismissFieldInput(_:)), for: .editingDidEnd)
|
textField.addTarget(self, action: #selector(dismissFieldInput), for: .editingDidEnd)
|
||||||
|
|
||||||
let tap = UITapGestureRecognizer(target: self, action: #selector(startEditing))
|
let tap = UITapGestureRecognizer(target: self, action: #selector(startEditing))
|
||||||
entryFieldContainer.addGestureRecognizer(tap)
|
entryFieldContainer.addGestureRecognizer(tap)
|
||||||
@ -194,37 +198,31 @@ import UIKit
|
|||||||
@objc open override func updateView(_ size: CGFloat) {
|
@objc open override func updateView(_ size: CGFloat) {
|
||||||
super.updateView(size)
|
super.updateView(size)
|
||||||
|
|
||||||
textField.font = MFStyler.fontRegularBodyLarge()
|
textField.font = Styler.Font.RegularBodyLarge.getFont()
|
||||||
layoutIfNeeded()
|
layoutIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
|
|
||||||
textField.font = MFStyler.fontRegularBodyLarge()
|
textField.font = Styler.Font.RegularBodyLarge.getFont()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc deinit {
|
|
||||||
setBothTextDelegates(to: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
|
@objc public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
|
||||||
observingTextFieldDelegate = delegate
|
observingTextFieldDelegate = delegate
|
||||||
uiTextFieldDelegate = delegate
|
uiTextFieldDelegate = delegate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open func setupTextFieldToolbar() {
|
||||||
|
let observingDelegate = observingTextFieldDelegate ?? self
|
||||||
|
textField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate,
|
||||||
|
action: #selector(observingDelegate.dismissFieldInput))
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Observing for Change (TextFieldDelegate)
|
// MARK: - Observing for Change (TextFieldDelegate)
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public func defaultValidationBlock() {
|
|
||||||
|
|
||||||
validationBlock = { enteredValue in
|
|
||||||
guard let enteredValue = enteredValue else { return false }
|
|
||||||
return enteredValue.count > 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
@objc override open func resignFirstResponder() -> Bool {
|
@objc override open func resignFirstResponder() -> Bool {
|
||||||
if validateWhenDoneEditing {
|
if validateWhenDoneEditing {
|
||||||
@ -240,11 +238,11 @@ import UIKit
|
|||||||
text = textField.text
|
text = textField.text
|
||||||
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public func updateValidation(_ isValid: Bool) {
|
@objc public func updateValidation(_ isValid: Bool) {
|
||||||
let previousValidity = self.isValid
|
let previousValidity = self.isValid
|
||||||
self.isValid = isValid
|
self.isValid = isValid
|
||||||
|
|
||||||
if previousValidity && !isValid {
|
if previousValidity && !isValid {
|
||||||
showError = true
|
showError = true
|
||||||
observingTextFieldDelegate?.isInvalid?(textfield: self)
|
observingTextFieldDelegate?.isInvalid?(textfield: self)
|
||||||
@ -276,10 +274,30 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func dismissFieldInput(_ sender: Any?) {
|
@objc public func dismissFieldInput(_ sender: Any?) {
|
||||||
resignFirstResponder()
|
resignFirstResponder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func showErrorView(_ show: Bool) {
|
||||||
|
|
||||||
|
if show {
|
||||||
|
entryFieldContainer.addSubview(errorImage)
|
||||||
|
|
||||||
|
textFieldTrailingConstraint?.isActive = false
|
||||||
|
textFieldTrailingConstraint = errorImage.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two)
|
||||||
|
textFieldTrailingConstraint?.isActive = true
|
||||||
|
|
||||||
|
entryFieldContainer.trailingAnchor.constraint(equalTo: errorImage.trailingAnchor, constant: Padding.Three).isActive = true
|
||||||
|
errorImage.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true
|
||||||
|
|
||||||
|
} else {
|
||||||
|
errorImage.removeFromSuperview()
|
||||||
|
textFieldTrailingConstraint?.isActive = false
|
||||||
|
textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two)
|
||||||
|
textFieldTrailingConstraint?.isActive = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - MoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -288,44 +306,39 @@ import UIKit
|
|||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
|
||||||
guard let model = model as? TextEntryFieldModel else { return }
|
guard let model = model as? TextEntryFieldModel else { return }
|
||||||
|
|
||||||
model.updateUI = { [weak self] in
|
model.updateUI = { [weak self] in
|
||||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||||
if self?.isSelected ?? false {
|
guard let self = self else { return }
|
||||||
self?.updateValidation(model.isValid ?? true)
|
|
||||||
|
if self.isSelected {
|
||||||
|
self.updateValidation(model.isValid ?? true)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
self.delegateObject = delegateObject
|
self.delegateObject = delegateObject
|
||||||
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
|
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
|
||||||
textColor.enabled = model.enabledTextColor?.uiColor
|
|
||||||
textColor.disabled = model.disabledTextColor?.uiColor
|
|
||||||
text = model.text
|
text = model.text
|
||||||
placeholder = model.placeholder
|
placeholder = model.placeholder
|
||||||
|
|
||||||
switch model.type {
|
switch model.type {
|
||||||
case .password:
|
case .password, .secure:
|
||||||
textField.isSecureTextEntry = true
|
textField.isSecureTextEntry = true
|
||||||
|
|
||||||
case .number:
|
case .number:
|
||||||
textField.keyboardType = .numberPad
|
textField.keyboardType = .numberPad
|
||||||
|
|
||||||
case .email:
|
case .email:
|
||||||
textField.keyboardType = .emailAddress
|
textField.keyboardType = .emailAddress
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if let regex = model.regex, !regex.isEmpty {
|
|
||||||
validationBlock = { enteredValue in
|
|
||||||
guard let value = enteredValue else { return false }
|
|
||||||
return MVMCoreUIUtility.validate(value, withRegularExpression: regex)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
defaultValidationBlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate
|
uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate
|
||||||
observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate
|
observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate
|
||||||
textField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: observingTextFieldDelegate ?? self)
|
setupTextFieldToolbar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,9 +8,13 @@
|
|||||||
|
|
||||||
|
|
||||||
@objcMembers public class TextEntryFieldModel: EntryFieldModel {
|
@objcMembers public class TextEntryFieldModel: EntryFieldModel {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Types
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public enum EntryType: String, Codable {
|
public enum EntryType: String, Codable {
|
||||||
case password
|
case password
|
||||||
|
case secure
|
||||||
case number
|
case number
|
||||||
case email
|
case email
|
||||||
}
|
}
|
||||||
@ -24,10 +28,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public var placeholder: String?
|
public var placeholder: String?
|
||||||
public var enabledTextColor: Color?
|
public var enabledTextColor: Color = Color(uiColor: .mvmBlack)
|
||||||
public var disabledTextColor: Color?
|
public var disabledTextColor: Color = Color(uiColor: .mvmCoolGray3)
|
||||||
public var type: EntryType?
|
public var type: EntryType?
|
||||||
public var regex: String?
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
@ -35,38 +38,38 @@
|
|||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case text
|
|
||||||
case placeholder
|
case placeholder
|
||||||
case enabledTextColor
|
case enabledTextColor
|
||||||
case disabledTextColor
|
case disabledTextColor
|
||||||
case type
|
case type
|
||||||
case regex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Codec
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
|
||||||
placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder)
|
placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder)
|
||||||
enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor)
|
|
||||||
disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor)
|
|
||||||
type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type)
|
type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type)
|
||||||
regex = try typeContainer.decodeIfPresent(String.self, forKey: .regex)
|
|
||||||
|
if let enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor) {
|
||||||
|
self.enabledTextColor = enabledTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
if let disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor) {
|
||||||
|
self.disabledTextColor = disabledTextColor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
try container.encodeIfPresent(text, forKey: .text)
|
|
||||||
try container.encodeIfPresent(placeholder, forKey: .placeholder)
|
try container.encodeIfPresent(placeholder, forKey: .placeholder)
|
||||||
try container.encodeIfPresent(enabledTextColor, forKey: .enabledTextColor)
|
try container.encode(enabledTextColor, forKey: .enabledTextColor)
|
||||||
try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor)
|
try container.encode(disabledTextColor, forKey: .disabledTextColor)
|
||||||
try container.encodeIfPresent(type, forKey: .type)
|
try container.encodeIfPresent(type, forKey: .type)
|
||||||
try container.encodeIfPresent(regex, forKey: .regex)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,8 +14,8 @@ import Foundation
|
|||||||
// MARK: - Outlets
|
// MARK: - Outlets
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
|
|
||||||
let leftTextLabel = Label.commonLabelB1(true)
|
let leftTextLabel = Label.createLabelBoldBodySmall(true)
|
||||||
let rightTextLabel = Label.commonLabelB1(true)
|
let rightTextLabel = Label.createLabelBoldBodySmall(true)
|
||||||
|
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
// MARK: - Constraints
|
// MARK: - Constraints
|
||||||
@ -23,6 +23,29 @@ import Foundation
|
|||||||
|
|
||||||
var rightTextLabelLeading: NSLayoutConstraint?
|
var rightTextLabelLeading: NSLayoutConstraint?
|
||||||
var leftTextLabelTrailing: NSLayoutConstraint?
|
var leftTextLabelTrailing: NSLayoutConstraint?
|
||||||
|
var rightTextLabelTrailing: NSLayoutConstraint?
|
||||||
|
|
||||||
|
private func constrainLeftLabelOnly() {
|
||||||
|
|
||||||
|
deactivateMiddleConstraint()
|
||||||
|
leftTextLabelTrailing?.isActive = false
|
||||||
|
leftTextLabelTrailing = layoutMarginsGuide.trailingAnchor.constraint(equalTo: leftTextLabel.trailingAnchor)
|
||||||
|
leftTextLabelTrailing?.isActive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private func constrainRightLabelOnly() {
|
||||||
|
|
||||||
|
deactivateMiddleConstraint()
|
||||||
|
rightTextLabelLeading?.isActive = false
|
||||||
|
rightTextLabelLeading = rightTextLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
|
||||||
|
rightTextLabelLeading?.isActive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private func deactivateMiddleConstraint() {
|
||||||
|
|
||||||
|
leftTextLabelTrailing?.isActive = false
|
||||||
|
rightTextLabelLeading?.isActive = false
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
// MARK: - Initialization
|
// MARK: - Initialization
|
||||||
@ -43,8 +66,6 @@ import Foundation
|
|||||||
override open func setupView() {
|
override open func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
|
|
||||||
guard subviews.isEmpty else { return }
|
|
||||||
|
|
||||||
addSubview(leftTextLabel)
|
addSubview(leftTextLabel)
|
||||||
addSubview(rightTextLabel)
|
addSubview(rightTextLabel)
|
||||||
|
|
||||||
@ -67,7 +88,7 @@ import Foundation
|
|||||||
// Resolves text layout issues found between both dynamically sized labels, number is not exact but performs as required.
|
// Resolves text layout issues found between both dynamically sized labels, number is not exact but performs as required.
|
||||||
if leftTextLabel.hasText && rightTextLabel.hasText {
|
if leftTextLabel.hasText && rightTextLabel.hasText {
|
||||||
let padding = MFStyler.defaultHorizontalPadding(forSize: size) * 2
|
let padding = MFStyler.defaultHorizontalPadding(forSize: size) * 2
|
||||||
let maximumTextWidth = (size - (padding + 16)) * 0.4
|
let maximumTextWidth = (size - (padding + Padding.Four)) * 0.4
|
||||||
// Subtracting 10 resolves issues of SE and iPad
|
// Subtracting 10 resolves issues of SE and iPad
|
||||||
rightTextLabel.preferredMaxLayoutWidth = round(maximumTextWidth) - 10
|
rightTextLabel.preferredMaxLayoutWidth = round(maximumTextWidth) - 10
|
||||||
} else {
|
} else {
|
||||||
@ -84,57 +105,38 @@ import Foundation
|
|||||||
leftTextLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
|
leftTextLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
|
||||||
leftTextLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor).isActive = true
|
leftTextLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor).isActive = true
|
||||||
|
|
||||||
let leftTextBottom = leftTextLabel.bottomAnchor.constraint(equalTo: bottomAnchor)
|
let leftTextBottom = bottomAnchor.constraint(equalTo: leftTextLabel.bottomAnchor)
|
||||||
leftTextBottom.priority = UILayoutPriority(249)
|
leftTextBottom.priority = UILayoutPriority(249)
|
||||||
leftTextBottom.isActive = true
|
leftTextBottom.isActive = true
|
||||||
|
|
||||||
bottomAnchor.constraint(greaterThanOrEqualTo: leftTextLabel.bottomAnchor).isActive = true
|
bottomAnchor.constraint(greaterThanOrEqualTo: leftTextLabel.bottomAnchor).isActive = true
|
||||||
|
|
||||||
rightTextLabelLeading = rightTextLabel.leadingAnchor.constraint(equalTo: leftTextLabel.trailingAnchor, constant: 16)
|
rightTextLabelLeading = rightTextLabel.leadingAnchor.constraint(equalTo: leftTextLabel.trailingAnchor, constant: Padding.Four)
|
||||||
rightTextLabelLeading?.isActive = true
|
rightTextLabelLeading?.isActive = true
|
||||||
|
|
||||||
rightTextLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
|
rightTextLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
|
||||||
let rightLayout = layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightTextLabel.trailingAnchor)
|
|
||||||
rightLayout.priority = UILayoutPriority(rawValue: 995)
|
|
||||||
rightLayout.isActive = true
|
|
||||||
|
|
||||||
let rightTextBottom = rightTextLabel.bottomAnchor.constraint(equalTo: bottomAnchor)
|
rightTextLabelTrailing = layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightTextLabel.trailingAnchor)
|
||||||
|
rightTextLabelTrailing?.isActive = true
|
||||||
|
|
||||||
|
let rightTextBottom = bottomAnchor.constraint(equalTo: rightTextLabel.bottomAnchor)
|
||||||
rightTextBottom.priority = UILayoutPriority(rawValue: 249)
|
rightTextBottom.priority = UILayoutPriority(rawValue: 249)
|
||||||
rightTextBottom.isActive = true
|
rightTextBottom.isActive = true
|
||||||
|
|
||||||
bottomAnchor.constraint(greaterThanOrEqualTo: rightTextLabel.bottomAnchor).isActive = true
|
bottomAnchor.constraint(greaterThanOrEqualTo: rightTextLabel.bottomAnchor).isActive = true
|
||||||
|
|
||||||
let leftTextWidth = leftTextLabel.widthAnchor.constraint(greaterThanOrEqualTo: layoutMarginsGuide.widthAnchor, multiplier: 0.6)
|
let leftTextWidth = leftTextLabel.widthAnchor.constraint(equalTo: layoutMarginsGuide.widthAnchor, multiplier: 0.6)
|
||||||
leftTextWidth.priority = UILayoutPriority(rawValue: 995)
|
leftTextWidth.priority = UILayoutPriority(rawValue: 995)
|
||||||
leftTextWidth.isActive = true
|
leftTextWidth.isActive = true
|
||||||
|
|
||||||
let rightTextWidth = rightTextLabel.widthAnchor.constraint(lessThanOrEqualTo: layoutMarginsGuide.widthAnchor, multiplier: 0.4)
|
let rightTextWidth = rightTextLabel.widthAnchor.constraint(equalTo: layoutMarginsGuide.widthAnchor, multiplier: 0.4)
|
||||||
rightTextWidth.priority = UILayoutPriority(rawValue: 906)
|
rightTextWidth.priority = UILayoutPriority(rawValue: 995)
|
||||||
rightTextWidth.isActive = true
|
rightTextWidth.isActive = true
|
||||||
|
|
||||||
leftTextLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 901), for: .horizontal)
|
rightTextLabel.setContentHuggingPriority(.required, for: .horizontal)
|
||||||
rightTextLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 902), for: .horizontal)
|
|
||||||
|
|
||||||
leftTextLabel.setContentHuggingPriority(.required, for: .vertical)
|
|
||||||
rightTextLabel.setContentHuggingPriority(.required, for: .vertical)
|
|
||||||
|
|
||||||
leftTextLabel.setContentCompressionResistancePriority(.required, for: .vertical)
|
leftTextLabel.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
rightTextLabel.setContentCompressionResistancePriority(.required, for: .vertical)
|
rightTextLabel.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
rightTextLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 902), for: .horizontal)
|
rightTextLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||||
}
|
|
||||||
|
|
||||||
private func constrainLeftLabel() {
|
|
||||||
|
|
||||||
deactivateMiddleConstraint()
|
|
||||||
leftTextLabelTrailing = layoutMarginsGuide.trailingAnchor.constraint(equalTo: leftTextLabel.trailingAnchor)
|
|
||||||
leftTextLabelTrailing?.isActive = true
|
|
||||||
}
|
|
||||||
|
|
||||||
private func constrainRightLabel() {
|
|
||||||
|
|
||||||
deactivateMiddleConstraint()
|
|
||||||
rightTextLabelLeading = rightTextLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
|
|
||||||
rightTextLabelLeading?.isActive = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override open func reset() {
|
override open func reset() {
|
||||||
@ -144,31 +146,31 @@ import Foundation
|
|||||||
constrainBothLabels()
|
constrainBothLabels()
|
||||||
leftTextLabel.text = ""
|
leftTextLabel.text = ""
|
||||||
rightTextLabel.text = ""
|
rightTextLabel.text = ""
|
||||||
|
leftTextLabel.textAlignment = .left
|
||||||
|
rightTextLabel.textAlignment = .right
|
||||||
backgroundColor = nil
|
backgroundColor = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private func deactivateMiddleConstraint() {
|
|
||||||
|
|
||||||
leftTextLabelTrailing?.isActive = false
|
|
||||||
rightTextLabelLeading?.isActive = false
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
// MARK: - Atomization
|
// MARK: - Atomization
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
|
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
guard let leftRightLabelModel = model as? LeftRightLabelModel else {
|
|
||||||
return
|
guard let leftRightLabelModel = model as? LeftRightLabelModel else { return }
|
||||||
}
|
|
||||||
leftTextLabel.set(with: leftRightLabelModel.leftText, delegateObject, additionalData)
|
leftTextLabel.set(with: leftRightLabelModel.leftText, delegateObject, additionalData)
|
||||||
rightTextLabel.setOptional(with: leftRightLabelModel.rightText, delegateObject, additionalData)
|
rightTextLabel.setOptional(with: leftRightLabelModel.rightText, delegateObject, additionalData)
|
||||||
|
|
||||||
|
// Label defaults to .left if no textAlignment value is provided in model.
|
||||||
|
rightTextLabel.textAlignment = leftRightLabelModel.rightText?.textAlignment ?? .right
|
||||||
|
|
||||||
if !leftTextLabel.hasText {
|
if !leftTextLabel.hasText {
|
||||||
constrainRightLabel()
|
constrainRightLabelOnly()
|
||||||
|
|
||||||
} else if !rightTextLabel.hasText {
|
} else if !rightTextLabel.hasText {
|
||||||
constrainLeftLabel()
|
constrainLeftLabelOnly()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,39 +9,27 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@objcMembers open class MultiProgress: View {
|
@objcMembers open class MultiProgress: View {
|
||||||
|
private let stack = Stack<StackModel>()
|
||||||
var multiProgressModel: MultiProgressBarModel? {
|
var multiProgressModel: MultiProgressBarModel? {
|
||||||
get { return model as? MultiProgressBarModel }
|
get { return model as? MultiProgressBarModel }
|
||||||
}
|
}
|
||||||
|
|
||||||
///passing value to progressList creates corresponding progress bars
|
public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
var progressList: Array<SingleProgressBarModel>? {
|
super.init(frame: .zero)
|
||||||
didSet {
|
set(with: model, delegateObject, additionalData)
|
||||||
for subview in subviews {
|
|
||||||
subview.removeFromSuperview()
|
|
||||||
}
|
|
||||||
guard (progressList?.count ?? 0) > 0 else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var previous: UIView?
|
|
||||||
for progressObject in progressList! {
|
|
||||||
guard progressObject.progress > 0.0 else {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
let view = UIView(frame: .zero)
|
|
||||||
view.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
addSubview(view)
|
|
||||||
view.backgroundColor = progressObject.progressColor.uiColor
|
|
||||||
view.widthAnchor.constraint(equalTo: widthAnchor, multiplier: progressObject.progress/100.0).isActive = true
|
|
||||||
view.leadingAnchor.constraint(equalTo: previous?.trailingAnchor ?? leadingAnchor).isActive = true
|
|
||||||
previous = view
|
|
||||||
NSLayoutConstraint.constraintPinSubview(view, pinTop: true, pinBottom: true, pinLeft: false, pinRight: false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var roundedRect: Bool = false {
|
public required init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
}
|
||||||
|
|
||||||
|
var roundedCorners: Bool = false {
|
||||||
didSet {
|
didSet {
|
||||||
if roundedRect {
|
if roundedCorners {
|
||||||
layer.cornerRadius = (thicknessConstraint?.constant ?? defaultHeight)/2
|
layer.cornerRadius = (thicknessConstraint?.constant ?? defaultHeight)/2
|
||||||
} else {
|
} else {
|
||||||
layer.cornerRadius = 0
|
layer.cornerRadius = 0
|
||||||
@ -57,28 +45,53 @@ import UIKit
|
|||||||
translatesAutoresizingMaskIntoConstraints = false
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
backgroundColor = .mfLightSilver()
|
backgroundColor = .mfLightSilver()
|
||||||
clipsToBounds = true
|
clipsToBounds = true
|
||||||
|
|
||||||
|
addSubview(stack)
|
||||||
|
NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
|
||||||
|
stack.backgroundColor = backgroundColor
|
||||||
|
stack.contentView.backgroundColor = .white
|
||||||
|
stack.model = StackModel(molecules: [], axis: .horizontal, spacing: 2)
|
||||||
|
stack.stackModel?.horizontalAlignment = .leading
|
||||||
|
|
||||||
if thicknessConstraint == nil {
|
if thicknessConstraint == nil {
|
||||||
thicknessConstraint = heightAnchor.constraint(equalToConstant: defaultHeight)
|
thicknessConstraint = heightAnchor.constraint(equalToConstant: defaultHeight)
|
||||||
thicknessConstraint?.isActive = true
|
thicknessConstraint?.isActive = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates the bars
|
||||||
|
open func set(with progressList: Array<SingleProgressBarModel>, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
stack.removeAllItemViews()
|
||||||
|
guard let stackModel = stack.stackModel else { return }
|
||||||
|
var views: [StackItem] = []
|
||||||
|
var models: [StackItemModel] = []
|
||||||
|
for progressObject in progressList {
|
||||||
|
guard progressObject.percent > 0.0 else { continue }
|
||||||
|
let model = StackItemModel(percent: Int(progressObject.percent), horizontalAlignment: .fill, verticalAlignment: .fill)
|
||||||
|
model.backgroundColor = progressObject.color
|
||||||
|
models.append(model)
|
||||||
|
views.append(StackItem())
|
||||||
|
}
|
||||||
|
stack.stackItems = views
|
||||||
|
stackModel.molecules = models
|
||||||
|
stack.set(with: stackModel, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
//MARK: - MoleculeViewProtocol
|
//MARK: - MoleculeViewProtocol
|
||||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
guard let multiProgressModel = multiProgressModel else {
|
guard let multiProgressModel = multiProgressModel else { return }
|
||||||
return
|
roundedCorners = multiProgressModel.roundedCorners ?? false
|
||||||
}
|
|
||||||
roundedRect = multiProgressModel.roundedRect ?? false
|
|
||||||
thicknessConstraint?.constant = multiProgressModel.thickness ?? defaultHeight
|
thicknessConstraint?.constant = multiProgressModel.thickness ?? defaultHeight
|
||||||
progressList = multiProgressModel.progressList
|
stack.model?.backgroundColor = model.backgroundColor
|
||||||
|
set(with: multiProgressModel.progressList, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
backgroundColor = .mfLightSilver()
|
backgroundColor = .mfLightSilver()
|
||||||
progressList = nil
|
stack.reset()
|
||||||
|
set(with: [], nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
|||||||
@ -9,12 +9,12 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class SingleProgressBarModel: Codable {
|
@objcMembers public class SingleProgressBarModel: Codable {
|
||||||
@Percent var progress: CGFloat
|
@Percent var percent: CGFloat
|
||||||
var progressColor: Color
|
var color: Color
|
||||||
|
|
||||||
init(_ progress: CGFloat, color: Color) {
|
init(_ percent: CGFloat, color: Color) {
|
||||||
self.progress = progress
|
self.percent = percent
|
||||||
self.progressColor = color
|
self.color = color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,13 +23,13 @@ import Foundation
|
|||||||
public var progressList: [SingleProgressBarModel]
|
public var progressList: [SingleProgressBarModel]
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var thickness: CGFloat?
|
public var thickness: CGFloat?
|
||||||
public var roundedRect: Bool?
|
public var roundedCorners: Bool?
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case progressList
|
case progressList
|
||||||
case thickness
|
case thickness
|
||||||
case roundedRect
|
case roundedCorners
|
||||||
case backgroundColor
|
case backgroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ import Foundation
|
|||||||
progressList = try typeContainer.decode([SingleProgressBarModel].self, forKey: .progressList)
|
progressList = try typeContainer.decode([SingleProgressBarModel].self, forKey: .progressList)
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness)
|
thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness)
|
||||||
roundedRect = try typeContainer.decodeIfPresent(Bool.self, forKey: .roundedRect)
|
roundedCorners = try typeContainer.decodeIfPresent(Bool.self, forKey: .roundedCorners)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -50,7 +50,7 @@ import Foundation
|
|||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
try container.encode(progressList, forKey: .progressList)
|
try container.encode(progressList, forKey: .progressList)
|
||||||
try container.encodeIfPresent(thickness, forKey: .thickness)
|
try container.encodeIfPresent(thickness, forKey: .thickness)
|
||||||
try container.encodeIfPresent(roundedRect, forKey: .roundedRect)
|
try container.encodeIfPresent(roundedCorners, forKey: .roundedCorners)
|
||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import Foundation
|
|||||||
var thickness: CGFloat = 8.0 {
|
var thickness: CGFloat = 8.0 {
|
||||||
willSet(newValue) {
|
willSet(newValue) {
|
||||||
heightAnchor.constraint(equalToConstant: newValue).isActive = true
|
heightAnchor.constraint(equalToConstant: newValue).isActive = true
|
||||||
if progressBarModel?.isRounded ?? false {
|
if progressBarModel?.roundedCorners ?? false {
|
||||||
layer.cornerRadius = newValue/2.0
|
layer.cornerRadius = newValue/2.0
|
||||||
} else {
|
} else {
|
||||||
progressViewStyle = .bar
|
progressViewStyle = .bar
|
||||||
@ -52,12 +52,11 @@ import Foundation
|
|||||||
|
|
||||||
//MARK: - MoleculeViewProtocol
|
//MARK: - MoleculeViewProtocol
|
||||||
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
guard let progressBarModel = model as? ProgressBarModel else {
|
guard let progressBarModel = model as? ProgressBarModel else { return }
|
||||||
return
|
self.progressBarModel = progressBarModel
|
||||||
}
|
|
||||||
thickness = progressBarModel.thickness ?? 8
|
thickness = progressBarModel.thickness ?? 8
|
||||||
progress = Float((progressBarModel.percent)/100.0)
|
progress = Float((progressBarModel.percent)/100.0)
|
||||||
progressTintColor = progressBarModel.progressColor.uiColor
|
progressTintColor = progressBarModel.color.uiColor
|
||||||
if let backgroundColor = progressBarModel.backgroundColor {
|
if let backgroundColor = progressBarModel.backgroundColor {
|
||||||
trackTintColor = backgroundColor.uiColor
|
trackTintColor = backgroundColor.uiColor
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,17 +11,17 @@ import Foundation
|
|||||||
@objcMembers public class ProgressBarModel: MoleculeModelProtocol {
|
@objcMembers public class ProgressBarModel: MoleculeModelProtocol {
|
||||||
public static var identifier: String = "progressBar"
|
public static var identifier: String = "progressBar"
|
||||||
@Percent public var percent: CGFloat
|
@Percent public var percent: CGFloat
|
||||||
public var progressColor: Color = Color(uiColor: .mfCerulean())
|
public var color: Color = Color(uiColor: .mfCerulean())
|
||||||
public var backgroundColor: Color? = Color(uiColor: .mfLightSilver())
|
public var backgroundColor: Color? = Color(uiColor: .mfLightSilver())
|
||||||
public var isRounded: Bool?
|
public var roundedCorners: Bool?
|
||||||
public var thickness: CGFloat?
|
public var thickness: CGFloat?
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case isRounded = "roundRect"
|
case roundedCorners
|
||||||
case thickness
|
case thickness
|
||||||
case percent
|
case percent
|
||||||
case progressColor
|
case color
|
||||||
case backgroundColor
|
case backgroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,13 +32,13 @@ import Foundation
|
|||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
percent = try typeContainer.decode(CGFloat.self, forKey: .percent)
|
percent = try typeContainer.decode(CGFloat.self, forKey: .percent)
|
||||||
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .progressColor) {
|
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) {
|
||||||
progressColor = color
|
self.color = color
|
||||||
}
|
}
|
||||||
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) {
|
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) {
|
||||||
backgroundColor = color
|
backgroundColor = color
|
||||||
}
|
}
|
||||||
isRounded = try typeContainer.decodeIfPresent(Bool.self, forKey: .isRounded)
|
roundedCorners = try typeContainer.decodeIfPresent(Bool.self, forKey: .roundedCorners)
|
||||||
thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness)
|
thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,9 +46,9 @@ import Foundation
|
|||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
try container.encode(percent, forKey: .percent)
|
try container.encode(percent, forKey: .percent)
|
||||||
try container.encode(progressColor, forKey: .progressColor)
|
try container.encode(color, forKey: .color)
|
||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
try container.encodeIfPresent(isRounded, forKey: .isRounded)
|
try container.encodeIfPresent(roundedCorners, forKey: .roundedCorners)
|
||||||
try container.encodeIfPresent(thickness, forKey: .thickness)
|
try container.encodeIfPresent(thickness, forKey: .thickness)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,13 +25,13 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
/// Holds the on and off colors for the container.
|
/// Holds the on and off colors for the container.
|
||||||
public var containerTintColor: (on: UIColor?, off: UIColor?)? = (on: .mvmGreen, off: .mvmBlack)
|
public var containerTintColor: (on: UIColor, off: UIColor) = (on: .mvmGreen, off: .mvmBlack)
|
||||||
|
|
||||||
/// Holds the on and off colors for the knob.
|
/// Holds the on and off colors for the knob.
|
||||||
public var knobTintColor: (on: UIColor?, off: UIColor?)? = (on: .mvmWhite, off: .mvmWhite)
|
public var knobTintColor: (on: UIColor, off: UIColor) = (on: .mvmWhite, off: .mvmWhite)
|
||||||
|
|
||||||
/// Holds the on and off colors for the disabled state..
|
/// Holds the on and off colors for the disabled state..
|
||||||
public var disabledTintColor: (container: UIColor?, knob: UIColor?)? = (container: .mvmCoolGray3, knob: .mvmWhite)
|
public var disabledTintColor: (container: UIColor, knob: UIColor) = (container: .mvmCoolGray3, knob: .mvmWhite)
|
||||||
|
|
||||||
/// Set this flag to false if you do not want to animate state changes.
|
/// Set this flag to false if you do not want to animate state changes.
|
||||||
public var isAnimated = true
|
public var isAnimated = true
|
||||||
@ -62,8 +62,8 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
didSet {
|
didSet {
|
||||||
isUserInteractionEnabled = isEnabled
|
isUserInteractionEnabled = isEnabled
|
||||||
changeStateNoAnimation(isEnabled ? isOn : false)
|
changeStateNoAnimation(isEnabled ? isOn : false)
|
||||||
backgroundColor = isEnabled ? containerTintColor?.off : disabledTintColor?.container
|
backgroundColor = isEnabled ? (isOn ? containerTintColor.on : containerTintColor.off) : disabledTintColor.container
|
||||||
knobView.backgroundColor = isEnabled ? knobTintColor?.off : disabledTintColor?.knob
|
knobView.backgroundColor = isEnabled ? (isOn ? knobTintColor.on : knobTintColor.off) : disabledTintColor.knob
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,12 +80,12 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
if isAnimated {
|
if isAnimated {
|
||||||
UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: {
|
UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: {
|
||||||
if self.isOn {
|
if self.isOn {
|
||||||
self.knobView.backgroundColor = self.knobTintColor?.on
|
self.knobView.backgroundColor = self.knobTintColor.on
|
||||||
self.backgroundColor = self.containerTintColor?.on
|
self.backgroundColor = self.containerTintColor.on
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
self.knobView.backgroundColor = self.knobTintColor?.off
|
self.knobView.backgroundColor = self.knobTintColor.off
|
||||||
self.backgroundColor = self.containerTintColor?.off
|
self.backgroundColor = self.containerTintColor.off
|
||||||
}
|
}
|
||||||
}, completion: nil)
|
}, completion: nil)
|
||||||
|
|
||||||
@ -96,12 +96,12 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
}, completion: nil)
|
}, completion: nil)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
backgroundColor = isOn ? containerTintColor?.on : containerTintColor?.off
|
backgroundColor = isOn ? containerTintColor.on : containerTintColor.off
|
||||||
knobView.backgroundColor = isOn ? knobTintColor?.on : knobTintColor?.off
|
knobView.backgroundColor = isOn ? knobTintColor.on : knobTintColor.off
|
||||||
self.constrainKnob()
|
self.constrainKnob()
|
||||||
}
|
}
|
||||||
|
|
||||||
(model as? ToggleModel)?.state = isOn
|
toggleModel?.state = isOn
|
||||||
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||||
accessibilityValue = isOn ? MVMCoreUIUtility.hardcodedString(withKey: "AccOn") : MVMCoreUIUtility.hardcodedString(withKey: "AccOff")
|
accessibilityValue = isOn ? MVMCoreUIUtility.hardcodedString(withKey: "AccOn") : MVMCoreUIUtility.hardcodedString(withKey: "AccOff")
|
||||||
setNeedsLayout()
|
setNeedsLayout()
|
||||||
@ -109,6 +109,10 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var toggleModel: ToggleModel? {
|
||||||
|
return model as? ToggleModel
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Delegate
|
// MARK: - Delegate
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -127,8 +131,26 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
private var widthConstraint: NSLayoutConstraint?
|
private var widthConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
private func constrainKnob() {
|
private func constrainKnob() {
|
||||||
knobLeadingConstraint?.isActive = !isOn
|
|
||||||
knobTrailingConstraint?.isActive = isOn
|
knobLeadingConstraint?.isActive = false
|
||||||
|
knobTrailingConstraint?.isActive = false
|
||||||
|
|
||||||
|
_ = isOn ? constrainKnobOn() : constrainKnobOff()
|
||||||
|
|
||||||
|
knobTrailingConstraint?.isActive = true
|
||||||
|
knobLeadingConstraint?.isActive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private func constrainKnobOn() {
|
||||||
|
|
||||||
|
knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 1)
|
||||||
|
knobLeadingConstraint = knobView.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func constrainKnobOff() {
|
||||||
|
|
||||||
|
knobTrailingConstraint = trailingAnchor.constraint(greaterThanOrEqualTo: knobView.trailingAnchor)
|
||||||
|
knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -185,11 +207,13 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
|
|
||||||
layer.cornerRadius = Self.getContainerHeight() / 2.0
|
layer.cornerRadius = Self.getContainerHeight() / 2.0
|
||||||
knobView.layer.cornerRadius = Self.getKnobHeight() / 2.0
|
knobView.layer.cornerRadius = Self.getKnobHeight() / 2.0
|
||||||
|
|
||||||
|
changeStateNoAnimation(isOn)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func setupView() {
|
public override func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
guard subviews.isEmpty else { return }
|
|
||||||
isAccessibilityElement = true
|
isAccessibilityElement = true
|
||||||
accessibilityTraits = .button
|
accessibilityTraits = .button
|
||||||
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccToggleHint")
|
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccToggleHint")
|
||||||
@ -202,7 +226,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
widthConstraint?.isActive = true
|
widthConstraint?.isActive = true
|
||||||
|
|
||||||
layer.cornerRadius = Self.containerSize.height / 2.0
|
layer.cornerRadius = Self.containerSize.height / 2.0
|
||||||
backgroundColor = containerTintColor?.off
|
backgroundColor = containerTintColor.off
|
||||||
|
|
||||||
addSubview(knobView)
|
addSubview(knobView)
|
||||||
|
|
||||||
@ -214,19 +238,16 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
knobView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor).isActive = true
|
knobView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor).isActive = true
|
||||||
bottomAnchor.constraint(greaterThanOrEqualTo: knobView.bottomAnchor).isActive = true
|
bottomAnchor.constraint(greaterThanOrEqualTo: knobView.bottomAnchor).isActive = true
|
||||||
|
|
||||||
knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 1)
|
constrainKnobOff()
|
||||||
knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1)
|
|
||||||
knobLeadingConstraint?.isActive = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func reset() {
|
public override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
|
|
||||||
backgroundColor = containerTintColor?.off
|
backgroundColor = containerTintColor.off
|
||||||
knobView.backgroundColor = knobTintColor?.off
|
knobView.backgroundColor = knobTintColor.off
|
||||||
isAnimated = false
|
accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel")
|
||||||
isOn = false
|
isAnimated = true
|
||||||
constrainKnob()
|
|
||||||
didToggleAction = nil
|
didToggleAction = nil
|
||||||
shouldToggleAction = { return true }
|
shouldToggleAction = { return true }
|
||||||
}
|
}
|
||||||
@ -344,26 +365,19 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
|
|
||||||
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
|
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
|
||||||
|
|
||||||
if let color = model.onTintColor?.uiColor {
|
containerTintColor.on = model.onTintColor.uiColor
|
||||||
containerTintColor?.on = color
|
containerTintColor.off = model.offTintColor.uiColor
|
||||||
}
|
knobTintColor.on = model.onKnobTintColor.uiColor
|
||||||
|
knobTintColor.off = model.offKnobTintColor.uiColor
|
||||||
if let color = model.offTintColor?.uiColor {
|
isOn = model.state
|
||||||
containerTintColor?.off = color
|
changeStateNoAnimation(isOn)
|
||||||
}
|
|
||||||
|
|
||||||
if let color = model.onKnobTintColor?.uiColor {
|
|
||||||
knobTintColor?.on = color
|
|
||||||
}
|
|
||||||
|
|
||||||
if let color = model.offKnobTintColor?.uiColor {
|
|
||||||
knobTintColor?.off = color
|
|
||||||
}
|
|
||||||
|
|
||||||
changeStateNoAnimation(model.state)
|
|
||||||
isAnimated = model.animated
|
isAnimated = model.animated
|
||||||
isEnabled = model.enabled
|
isEnabled = model.enabled
|
||||||
|
|
||||||
|
if let accessibileString = model.accessibilityText {
|
||||||
|
accessibilityLabel = accessibileString
|
||||||
|
}
|
||||||
|
|
||||||
if let actionMap = model.action?.toJSON() {
|
if let actionMap = model.action?.toJSON() {
|
||||||
didToggleAction = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) }
|
didToggleAction = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,8 +8,12 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableModelProtocol {
|
|
||||||
|
|
||||||
|
public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableModelProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public static var identifier: String = "toggle"
|
public static var identifier: String = "toggle"
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var state: Bool = false
|
public var state: Bool = false
|
||||||
@ -18,10 +22,10 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
|||||||
public var action: ActionModelProtocol?
|
public var action: ActionModelProtocol?
|
||||||
public var alternateAction: ActionModelProtocol?
|
public var alternateAction: ActionModelProtocol?
|
||||||
public var accessibilityText: String?
|
public var accessibilityText: String?
|
||||||
public var onTintColor: Color?
|
public var onTintColor: Color = Color(uiColor: .mvmGreen)
|
||||||
public var offTintColor: Color?
|
public var offTintColor: Color = Color(uiColor: .mvmBlack)
|
||||||
public var onKnobTintColor: Color?
|
public var onKnobTintColor: Color = Color(uiColor: .mvmWhite)
|
||||||
public var offKnobTintColor: Color?
|
public var offKnobTintColor: Color = Color(uiColor: .mvmWhite)
|
||||||
|
|
||||||
public var fieldKey: String?
|
public var fieldKey: String?
|
||||||
public var groupName: String = FormValidator.defaultGroupName
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
@ -75,19 +79,35 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
|||||||
if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) {
|
if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) {
|
||||||
self.state = state
|
self.state = state
|
||||||
}
|
}
|
||||||
|
|
||||||
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
||||||
self.enabled = enabled
|
self.enabled = enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
if let animated = try typeContainer.decodeIfPresent(Bool.self, forKey: .animated) {
|
if let animated = try typeContainer.decodeIfPresent(Bool.self, forKey: .animated) {
|
||||||
self.animated = animated
|
self.animated = animated
|
||||||
}
|
}
|
||||||
|
|
||||||
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
|
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
|
||||||
alternateAction = try typeContainer.decodeModelIfPresent(codingKey: .alternateAction)
|
alternateAction = try typeContainer.decodeModelIfPresent(codingKey: .alternateAction)
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
onTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onTintColor)
|
|
||||||
offTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offTintColor)
|
if let onTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onTintColor) {
|
||||||
onKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onKnobTintColor)
|
self.onTintColor = onTintColor
|
||||||
offKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offKnobTintColor)
|
}
|
||||||
|
|
||||||
|
if let offTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offTintColor) {
|
||||||
|
self.offTintColor = offTintColor
|
||||||
|
}
|
||||||
|
|
||||||
|
if let onKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onKnobTintColor) {
|
||||||
|
self.onKnobTintColor = onKnobTintColor
|
||||||
|
}
|
||||||
|
|
||||||
|
if let offKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offKnobTintColor) {
|
||||||
|
self.offKnobTintColor = offKnobTintColor
|
||||||
|
}
|
||||||
|
|
||||||
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||||
|
|
||||||
baseValue = state
|
baseValue = state
|
||||||
@ -106,10 +126,10 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
|||||||
try container.encode(state, forKey: .state)
|
try container.encode(state, forKey: .state)
|
||||||
try container.encode(animated, forKey: .animated)
|
try container.encode(animated, forKey: .animated)
|
||||||
try container.encode(enabled, forKey: .enabled)
|
try container.encode(enabled, forKey: .enabled)
|
||||||
try container.encodeIfPresent(onTintColor, forKey: .onTintColor)
|
try container.encode(onTintColor, forKey: .onTintColor)
|
||||||
try container.encodeIfPresent(onKnobTintColor, forKey: .onKnobTintColor)
|
try container.encode(onKnobTintColor, forKey: .onKnobTintColor)
|
||||||
try container.encodeIfPresent(onKnobTintColor, forKey: .onKnobTintColor)
|
try container.encode(onKnobTintColor, forKey: .onKnobTintColor)
|
||||||
try container.encodeIfPresent(offKnobTintColor, forKey: .offKnobTintColor)
|
try container.encode(offKnobTintColor, forKey: .offKnobTintColor)
|
||||||
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
try container.encodeIfPresent(groupName, forKey: .groupName)
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// GraphView.swift
|
// Wheel.swift
|
||||||
// MobileFirstFramework
|
// MobileFirstFramework
|
||||||
//
|
//
|
||||||
// Created by Ryan on 10/24/19.
|
// Created by Ryan on 10/24/19.
|
||||||
@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@objcMembers open class GraphView: View, MVMCoreUIViewConstrainingProtocol {
|
@objcMembers open class Wheel: View, MVMCoreUIViewConstrainingProtocol {
|
||||||
|
|
||||||
var heightConstraint: NSLayoutConstraint?
|
var heightConstraint: NSLayoutConstraint?
|
||||||
var gradientLayer: CALayer?
|
var gradientLayer: CALayer?
|
||||||
var graphModel: CircleProgressModel? {
|
var graphModel: WheelModel? {
|
||||||
return model as? CircleProgressModel
|
return model as? WheelModel
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: setup
|
// MARK: setup
|
||||||
@ -28,7 +28,7 @@ import UIKit
|
|||||||
|
|
||||||
override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
guard let model = model as? CircleProgressModel else { return }
|
guard let model = model as? WheelModel else { return }
|
||||||
createGraphCircle(model)
|
createGraphCircle(model)
|
||||||
rotationAnimation(model)
|
rotationAnimation(model)
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: circle
|
// MARK: circle
|
||||||
open func createGraphCircle(_ graphObject: CircleProgressModel) {
|
open func createGraphCircle(_ graphObject: WheelModel) {
|
||||||
if let sublayers = layer.sublayers {
|
if let sublayers = layer.sublayers {
|
||||||
for sublayer in sublayers {
|
for sublayer in sublayers {
|
||||||
sublayer.removeAllAnimations()
|
sublayer.removeAllAnimations()
|
||||||
@ -56,7 +56,7 @@ import UIKit
|
|||||||
|
|
||||||
//begin point will be at the bottom, clockwise direction
|
//begin point will be at the bottom, clockwise direction
|
||||||
let path = UIBezierPath(arcCenter: CGPoint(x: radius
|
let path = UIBezierPath(arcCenter: CGPoint(x: radius
|
||||||
, y: radius), radius: radius - graphObject.lineWidth/2.0, startAngle: CGFloat(GraphView.getPiValue(90.0)), endAngle: CGFloat(GraphView.getPiValue(90.0 + 360.0)), clockwise: true)
|
, y: radius), radius: radius - graphObject.lineWidth/2.0, startAngle: CGFloat(Wheel.getPiValue(90.0)), endAngle: CGFloat(Wheel.getPiValue(90.0 + 360.0)), clockwise: true)
|
||||||
path.lineWidth = graphObject.lineWidth
|
path.lineWidth = graphObject.lineWidth
|
||||||
|
|
||||||
let circleLayer = CAShapeLayer()
|
let circleLayer = CAShapeLayer()
|
||||||
@ -83,7 +83,7 @@ import UIKit
|
|||||||
| | |
|
| | |
|
||||||
-------------
|
-------------
|
||||||
*/
|
*/
|
||||||
func createGradientLayer(_ graphObject: CircleProgressModel) -> CALayer {
|
func createGradientLayer(_ graphObject: WheelModel) -> CALayer {
|
||||||
let containLayer = CALayer()
|
let containLayer = CALayer()
|
||||||
containLayer.frame = CGRect(x: 0, y: 0, width: graphObject.diameter, height: graphObject.diameter)
|
containLayer.frame = CGRect(x: 0, y: 0, width: graphObject.diameter, height: graphObject.diameter)
|
||||||
let radius = graphObject.diameter / 2.0
|
let radius = graphObject.diameter / 2.0
|
||||||
@ -151,18 +151,18 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
//MARK: Animation
|
//MARK: Animation
|
||||||
func rotationAnimation(_ object: CircleProgressModel) {
|
func rotationAnimation(_ object: WheelModel) {
|
||||||
MVMCoreDispatchUtility.performBlock(onMainThread:{
|
MVMCoreDispatchUtility.performBlock(onMainThread:{
|
||||||
let rotation = CABasicAnimation(keyPath: "transform.rotation")
|
let rotation = CABasicAnimation(keyPath: "transform.rotation")
|
||||||
let animationHandler = GraphViewAnimationHandler.shared
|
let animationHandler = WheelAnimationHandler.shared
|
||||||
let startAngle = animationHandler.getAnimationStartAngle(object.duration, CACurrentMediaTime())
|
let startAngle = animationHandler.getAnimationStartAngle(object.duration, CACurrentMediaTime())
|
||||||
if startAngle == 0.0 {
|
if startAngle == 0.0 {
|
||||||
animationHandler.storeAnimation(object.duration, CACurrentMediaTime())
|
animationHandler.storeAnimation(object.duration, CACurrentMediaTime())
|
||||||
}
|
}
|
||||||
var fromValue = GraphView.getPiValue(0.0 + startAngle), toValue = GraphView.getPiValue(360.0 + startAngle)
|
var fromValue = Wheel.getPiValue(0.0 + startAngle), toValue = Wheel.getPiValue(360.0 + startAngle)
|
||||||
if !object.clockwise {
|
if !object.clockwise {
|
||||||
fromValue = GraphView.getPiValue(360.0 - startAngle)
|
fromValue = Wheel.getPiValue(360.0 - startAngle)
|
||||||
toValue = GraphView.getPiValue(0.0 - startAngle)
|
toValue = Wheel.getPiValue(0.0 - startAngle)
|
||||||
}
|
}
|
||||||
rotation.fromValue = fromValue
|
rotation.fromValue = fromValue
|
||||||
rotation.toValue = toValue
|
rotation.toValue = toValue
|
||||||
@ -180,7 +180,7 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extension GraphView: CAAnimationDelegate {
|
extension Wheel: CAAnimationDelegate {
|
||||||
public func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
|
public func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
|
||||||
if let object = graphModel {
|
if let object = graphModel {
|
||||||
rotationAnimation(object)
|
rotationAnimation(object)
|
||||||
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// GraphViewAnimationHandler.swift
|
// WheelAnimationHandler.swift
|
||||||
// MobileFirstFramework
|
// MobileFirstFramework
|
||||||
//
|
//
|
||||||
// Created by Ryan on 10/29/19.
|
// Created by Ryan on 10/29/19.
|
||||||
@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@objcMembers open class GraphViewAnimationHandler: NSObject {
|
@objcMembers open class WheelAnimationHandler: NSObject {
|
||||||
|
|
||||||
/// duration : CACurrentMediaTime()
|
/// duration : CACurrentMediaTime()
|
||||||
private var animations = [Double: Double]()
|
private var animations = [Double: Double]()
|
||||||
|
|
||||||
static let shared = GraphViewAnimationHandler()
|
static let shared = WheelAnimationHandler()
|
||||||
|
|
||||||
open func storeAnimation(_ duration: Double, _ currentTime: CFTimeInterval) {
|
open func storeAnimation(_ duration: Double, _ currentTime: CFTimeInterval) {
|
||||||
guard animations[duration] == nil else {
|
guard animations[duration] == nil else {
|
||||||
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// CircleProgressModel.swift
|
// WheelModel.swift
|
||||||
// MVMCoreUI
|
// MVMCoreUI
|
||||||
//
|
//
|
||||||
// Created by Scott Pfeil on 1/13/20.
|
// Created by Scott Pfeil on 1/13/20.
|
||||||
@ -16,9 +16,9 @@ public enum GraphStyle: String, Codable {
|
|||||||
case unlimited, safetyMode
|
case unlimited, safetyMode
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CircleProgressModel: MoleculeModelProtocol {
|
public class WheelModel: MoleculeModelProtocol {
|
||||||
|
|
||||||
public static var identifier: String = "circleProgress"
|
public static var identifier: String = "wheel"
|
||||||
public var style: GraphStyle = .unlimited {
|
public var style: GraphStyle = .unlimited {
|
||||||
didSet {
|
didSet {
|
||||||
updateStyle()
|
updateStyle()
|
||||||
37
MVMCoreUI/Atomic/Extensions/UIDatePicker+Extension.swift
Normal file
37
MVMCoreUI/Atomic/Extensions/UIDatePicker+Extension.swift
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// UIDatePicker+Extension.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kevin Christiano on 4/14/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
public extension UIDatePicker {
|
||||||
|
|
||||||
|
class func addDatePicker(to textField: UITextField) -> UIDatePicker {
|
||||||
|
|
||||||
|
let datePicker = UIDatePicker()
|
||||||
|
datePicker.backgroundColor = .mvmWhite
|
||||||
|
datePicker.datePickerMode = .date
|
||||||
|
|
||||||
|
let locale = NSLocale.current as NSLocale
|
||||||
|
datePicker.locale = locale as Locale
|
||||||
|
datePicker.calendar = locale.object(forKey: .calendar) as? Calendar
|
||||||
|
textField.inputView = datePicker
|
||||||
|
|
||||||
|
return datePicker
|
||||||
|
}
|
||||||
|
|
||||||
|
class func addTimeAndDatePicker(to textField: UITextField) -> UIDatePicker {
|
||||||
|
|
||||||
|
let datePicker = UIDatePicker()
|
||||||
|
datePicker.backgroundColor = .mvmWhite
|
||||||
|
datePicker.datePickerMode = .time
|
||||||
|
textField.inputView = datePicker
|
||||||
|
|
||||||
|
return datePicker
|
||||||
|
}
|
||||||
|
}
|
||||||
38
MVMCoreUI/Atomic/Extensions/UIPickerView+Extension.swift
Normal file
38
MVMCoreUI/Atomic/Extensions/UIPickerView+Extension.swift
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// UIPickerView.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kevin Christiano on 4/14/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
public extension UIPickerView {
|
||||||
|
|
||||||
|
class func createPickerView() -> UIPickerView {
|
||||||
|
|
||||||
|
let picker = UIPickerView(frame: .zero)
|
||||||
|
picker.backgroundColor = .mvmWhite
|
||||||
|
picker.showsSelectionIndicator = true
|
||||||
|
return picker
|
||||||
|
}
|
||||||
|
|
||||||
|
class func addPicker(to textField: UITextField, delegate: TextFieldAndPickerDelegate?, dismissAction: Selector?) -> UIPickerView {
|
||||||
|
|
||||||
|
// Sets up the picker (same tag as the textfield)
|
||||||
|
let picker = createPickerView()
|
||||||
|
picker.delegate = delegate
|
||||||
|
picker.dataSource = delegate
|
||||||
|
picker.tag = textField.tag
|
||||||
|
textField.inputView = picker
|
||||||
|
|
||||||
|
// Adds a dismiss toolbar, since all fields with pickers should have one.
|
||||||
|
if let dismissAction = dismissAction {
|
||||||
|
UIToolbar.addDismissToolbar(to: textField, delegate: delegate, action: dismissAction)
|
||||||
|
}
|
||||||
|
|
||||||
|
return picker
|
||||||
|
}
|
||||||
|
}
|
||||||
56
MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift
Normal file
56
MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// UIToolbar+Extension.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kevin Christiano on 4/10/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol TextFieldOrView { }
|
||||||
|
|
||||||
|
extension UITextView: TextFieldOrView { }
|
||||||
|
extension UITextField: TextFieldOrView { }
|
||||||
|
|
||||||
|
|
||||||
|
public extension UIToolbar {
|
||||||
|
|
||||||
|
class func createEmptyToolbar() -> UIToolbar {
|
||||||
|
|
||||||
|
let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44))
|
||||||
|
toolbar.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleWidth]
|
||||||
|
toolbar.barStyle = .default
|
||||||
|
toolbar.barTintColor = .mvmCoolGray3
|
||||||
|
toolbar.tintColor = .mvmBlack
|
||||||
|
toolbar.isTranslucent = true
|
||||||
|
|
||||||
|
return toolbar
|
||||||
|
}
|
||||||
|
|
||||||
|
class func getToolbarWithDoneButton(delegate: Any?, action: Selector) -> UIToolbar {
|
||||||
|
|
||||||
|
let toolbar = createEmptyToolbar()
|
||||||
|
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
||||||
|
let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: action)
|
||||||
|
toolbar.setItems([space, button], animated: false)
|
||||||
|
|
||||||
|
return toolbar
|
||||||
|
}
|
||||||
|
|
||||||
|
class func addDismissToolbar(to object: TextFieldOrView, delegate: Any?, action: Selector) {
|
||||||
|
|
||||||
|
let toolbar = Self.getToolbarWithDoneButton(delegate: delegate, action: action)
|
||||||
|
|
||||||
|
switch object {
|
||||||
|
case is UITextField:
|
||||||
|
(object as? UITextField)?.inputAccessoryView = toolbar
|
||||||
|
|
||||||
|
case is UITextView:
|
||||||
|
(object as? UITextView)?.inputAccessoryView = toolbar
|
||||||
|
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -37,8 +37,7 @@ import Foundation
|
|||||||
/// Call to register all of the CoreUI molecules.
|
/// Call to register all of the CoreUI molecules.
|
||||||
public static func registerObjects() {
|
public static func registerObjects() {
|
||||||
// Stacks
|
// Stacks
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeStackView.self, viewModelClass: MoleculeStackModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeStackView.self, viewModelClass: StackModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: Stack<StackModel>.self, viewModelClass: StackModel.self)
|
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: UnOrderedList.self, viewModelClass: UnOrderedListModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: UnOrderedList.self, viewModelClass: UnOrderedListModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: NumberedList.self, viewModelClass: NumberedListModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: NumberedList.self, viewModelClass: NumberedListModel.self)
|
||||||
|
|
||||||
@ -70,6 +69,7 @@ import Foundation
|
|||||||
MoleculeObjectMapping.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: RadioBoxes.self, viewModelClass: RadioBoxesModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: RadioBoxes.self, viewModelClass: RadioBoxesModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: RadioSwatches.self, viewModelClass: RadioSwatchesModel.self)
|
||||||
|
|
||||||
// Other Atoms
|
// Other Atoms
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self)
|
||||||
@ -78,7 +78,7 @@ import Foundation
|
|||||||
MoleculeObjectMapping.shared()?.register(viewClass: DashLine.self, viewModelClass: DashLineModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: DashLine.self, viewModelClass: DashLineModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: MFLoadImageView.self, viewModelClass: ImageViewModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: MFLoadImageView.self, viewModelClass: ImageViewModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: Line.self, viewModelClass: LineModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: Line.self, viewModelClass: LineModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: GraphView.self, viewModelClass: CircleProgressModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: Wheel.self, viewModelClass: WheelModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: CheckboxLabel.self, viewModelClass: CheckboxLabelModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: CheckboxLabel.self, viewModelClass: CheckboxLabelModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: Arrow.self, viewModelClass: ArrowModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: Arrow.self, viewModelClass: ArrowModel.self)
|
||||||
@ -88,6 +88,7 @@ import Foundation
|
|||||||
// Horizontal Combination Molecules
|
// Horizontal Combination Molecules
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: Tabs.self, viewModelClass: TabsModel.self)
|
||||||
|
|
||||||
// Vertical Combination Molecules
|
// Vertical Combination Molecules
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self)
|
||||||
@ -120,6 +121,7 @@ import Foundation
|
|||||||
|
|
||||||
|
|
||||||
// Other Container Molecules
|
// Other Container Molecules
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeContainer.self, viewModelClass: MoleculeContainerModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeHeaderView.self, viewModelClass: MoleculeHeaderModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeHeaderView.self, viewModelClass: MoleculeHeaderModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: FooterView.self, viewModelClass: FooterModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: FooterView.self, viewModelClass: FooterModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: Scroller.self, viewModelClass: ScrollerModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: Scroller.self, viewModelClass: ScrollerModel.self)
|
||||||
@ -136,19 +138,23 @@ import Foundation
|
|||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxAllTextAndLinks.self, viewModelClass: ListLeftVariableCheckboxAllTextAndLinksModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxAllTextAndLinks.self, viewModelClass: ListLeftVariableCheckboxAllTextAndLinksModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonAndPaymentMethod.self, viewModelClass: ListLeftVariableRadioButtonAndPaymentMethodModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonAndPaymentMethod.self, viewModelClass: ListLeftVariableRadioButtonAndPaymentMethodModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonBodyText.self, viewModelClass: ListLeftVariableRadioButtonBodyTextModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonBodyText.self, viewModelClass: ListLeftVariableRadioButtonBodyTextModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxBodyText.self, viewModelClass: ListLeftVariableCheckboxBodyTextModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTotalData.self, viewModelClass: ListRightVariableTotalDataModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTotalData.self, viewModelClass: ListRightVariableTotalDataModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTextLinkAllTextAndLinks.self, viewModelClass: ListRightVariableTextLinkAllTextAndLinksModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTextLinkAllTextAndLinks.self, viewModelClass: ListRightVariableTextLinkAllTextAndLinksModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableButtonAllTextAndLinks.self, viewModelClass: ListRightVariableButtonAllTextAndLinksModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableButtonAllTextAndLinks.self, viewModelClass: ListRightVariableButtonAllTextAndLinksModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeBodyText.self, viewModelClass: ListRightVariablePriceChangeBodyTextModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeAllTextAndLinks.self, viewModelClass: ListRightVariablePriceChangeAllTextAndLinksModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextAllTextAndLinks.self, viewModelClass: ListOneColumnFullWidthTextAllTextAndLinksModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextAllTextAndLinks.self, viewModelClass: ListOneColumnFullWidthTextAllTextAndLinksModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextBodyText.self, viewModelClass: ListOneColumnFullWidthTextBodyTextModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextBodyText.self, viewModelClass: ListOneColumnFullWidthTextBodyTextModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnCompareChanges.self, viewModelClass: ListTwoColumnCompareChangesModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnCompareChanges.self, viewModelClass: ListTwoColumnCompareChangesModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnPriceDetails.self, viewModelClass: ListTwoColumnPriceDetailsModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnPriceDetails.self, viewModelClass: ListTwoColumnPriceDetailsModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnPriceDescription.self, viewModelClass: ListTwoColumnPriceDescriptionModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnPriceDescription.self, viewModelClass: ListTwoColumnPriceDescriptionModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnInternationalData.self, viewModelClass: ListThreeColumnInternationalDataModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnInternationalData.self, viewModelClass: ListThreeColumnInternationalDataModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnDataUsage.self, viewModelClass: ListThreeColumnDataUsageModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self)
|
||||||
|
|
||||||
// Designed Section Dividers
|
// Designed Section Dividers
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnPlanDataDivider.self, viewModelClass: ListThreeColumnPlanDataDividerModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnPlanDataDivider.self, viewModelClass: ListThreeColumnPlanDataDividerModel.self)
|
||||||
@ -164,6 +170,11 @@ import Foundation
|
|||||||
// Designed Headers
|
// Designed Headers
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2NoButtonsBodyText.self, viewModelClass: HeadersH2NoButtonsBodyTextModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2NoButtonsBodyText.self, viewModelClass: HeadersH2NoButtonsBodyTextModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2Buttons.self, viewModelClass: HeadersH2ButtonsModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2Buttons.self, viewModelClass: HeadersH2ButtonsModel.self)
|
||||||
|
|
||||||
|
// Device Items
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonMedium.self, viewModelClass: ListDeviceComplexButtonMediumModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkSmall.self, viewModelClass: ListDeviceComplexLinkSmallModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkMedium.self, viewModelClass: ListDeviceComplexLinkMediumModel.self)
|
||||||
|
|
||||||
// TODO: Need View
|
// TODO: Need View
|
||||||
try? ModelRegistry.register(TabsModel.self)
|
try? ModelRegistry.register(TabsModel.self)
|
||||||
|
|||||||
@ -25,8 +25,8 @@ public class HeadersH2NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol
|
|||||||
|
|
||||||
public override func setDefaults() {
|
public override func setDefaults() {
|
||||||
super.setDefaults()
|
super.setDefaults()
|
||||||
topMarginPadding = PaddingDefaultVerticalSpacing3
|
topPadding = PaddingDefaultVerticalSpacing3
|
||||||
bottomMarginPadding = PaddingDefaultVerticalSpacing3
|
bottomPadding = PaddingDefaultVerticalSpacing3
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -0,0 +1,79 @@
|
|||||||
|
//
|
||||||
|
// ListDeviceComplexButtonMedium.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Dhamodaram Nandi on 21/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
@objcMembers open class ListDeviceComplexButtonMedium: TableViewCell {
|
||||||
|
|
||||||
|
public var verticalStack: Stack<StackModel>
|
||||||
|
public let eyebrow = Label.createLabelRegularMicro(true)
|
||||||
|
public let headline = Label.createLabelBoldTitleMedium(true)
|
||||||
|
public let body = Label.createLabelRegularBodySmall(true)
|
||||||
|
public let body2 = Label.createLabelRegularBodySmall(true)
|
||||||
|
public let button = PillButton(frame: .zero)
|
||||||
|
public let rightImageView = MFLoadImageView()
|
||||||
|
public var stack: Stack<StackModel>
|
||||||
|
|
||||||
|
// MARK: - Initializers
|
||||||
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
rightImageView.addSizeConstraintsForAspectRatio = true
|
||||||
|
rightImageView.heightAnchor.constraint(equalToConstant: 116.0).isActive = true
|
||||||
|
rightImageView.widthAnchor.constraint(equalToConstant: 116.0).isActive = true
|
||||||
|
verticalStack = Stack<StackModel>.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)),
|
||||||
|
(view: headline, model: StackItemModel(horizontalAlignment: .leading)),
|
||||||
|
(view: body, model: StackItemModel(horizontalAlignment: .leading)),
|
||||||
|
(view: body2, model: StackItemModel(horizontalAlignment: .leading)),
|
||||||
|
(view: button, model: StackItemModel(spacing:16, horizontalAlignment: .leading))],
|
||||||
|
axis: .vertical, spacing: 0)
|
||||||
|
stack = Stack<StackModel>.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading, verticalAlignment: .leading)),
|
||||||
|
(view: rightImageView, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .center))],
|
||||||
|
axis: .horizontal)
|
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
public required init?(coder aDecoder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - MFViewProtocol
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
addMolecule(stack)
|
||||||
|
stack.restack()
|
||||||
|
verticalStack.restack()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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? ListDeviceComplexButtonMediumModel else { return }
|
||||||
|
verticalStack.updateContainedMolecules(with: [model.eyebrow,
|
||||||
|
model.headline,
|
||||||
|
model.body,
|
||||||
|
model.body2,
|
||||||
|
model.button],
|
||||||
|
delegateObject, additionalData)
|
||||||
|
rightImageView.set(with: model.image, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||||
|
return 120
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setDefault() {
|
||||||
|
eyebrow.styleRegularMicro(true)
|
||||||
|
headline.styleBoldTitleMedium(true)
|
||||||
|
body.styleRegularBodySmall(true)
|
||||||
|
body2.styleRegularBodySmall(true)
|
||||||
|
eyebrow.textColor = .mvmCoolGray6
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func reset() {
|
||||||
|
super.reset()
|
||||||
|
setDefault()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
//
|
||||||
|
// ListDeviceComplexButtonMediumModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Dhamodaram Nandi on 21/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
public class ListDeviceComplexButtonMediumModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "listDvcBtnM"
|
||||||
|
public var eyebrow: LabelModel?
|
||||||
|
public var headline: LabelModel?
|
||||||
|
public var body: LabelModel?
|
||||||
|
public var body2: LabelModel?
|
||||||
|
public var button: ButtonModel
|
||||||
|
public var image: ImageViewModel
|
||||||
|
|
||||||
|
public init(eyebrow: LabelModel, headline:LabelModel, body: LabelModel, body2: LabelModel, button: ButtonModel, image: ImageViewModel) {
|
||||||
|
self.eyebrow = eyebrow
|
||||||
|
self.headline = headline
|
||||||
|
self.body = body
|
||||||
|
self.body2 = body2
|
||||||
|
self.button = button
|
||||||
|
self.image = image
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defaults to set
|
||||||
|
override public func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
|
button.size = .tiny
|
||||||
|
button.style = .secondary
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case eyebrow
|
||||||
|
case headline
|
||||||
|
case body
|
||||||
|
case body2
|
||||||
|
case button
|
||||||
|
case image
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow)
|
||||||
|
headline = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .headline)
|
||||||
|
body = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body)
|
||||||
|
body2 = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body2)
|
||||||
|
button = try typeContainer.decode(ButtonModel.self, forKey: .button)
|
||||||
|
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
||||||
|
try super.init(from: decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func encode(to encoder: Encoder) throws {
|
||||||
|
try super.encode(to: encoder)
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
|
try container.encodeIfPresent(eyebrow, forKey: .eyebrow)
|
||||||
|
try container.encodeIfPresent(headline, forKey: .headline)
|
||||||
|
try container.encodeIfPresent(body, forKey: .body)
|
||||||
|
try container.encodeIfPresent(body2, forKey: .body2)
|
||||||
|
try container.encode(button, forKey: .button)
|
||||||
|
try container.encode(image, forKey: .image)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
//
|
||||||
|
// ListDeviceComplexLinkMedium.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 21/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
@objcMembers open class ListDeviceComplexLinkMedium: TableViewCell {
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Outlets
|
||||||
|
//-----------------------------------------------------
|
||||||
|
public let eyebrow = Label.createLabelRegularMicro(true)
|
||||||
|
public let headline = Label.createLabelBoldTitleMedium(true)
|
||||||
|
public let body = Label.createLabelRegularBodySmall(true)
|
||||||
|
public let body2 = Label.createLabelRegularBodySmall(true)
|
||||||
|
public let link = Link()
|
||||||
|
public let rightImage = MFLoadImageView()
|
||||||
|
let verticalStack: Stack<StackModel>
|
||||||
|
public let stack: Stack<StackModel>
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//------------------------------------------------------
|
||||||
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
rightImage.addSizeConstraintsForAspectRatio = true
|
||||||
|
rightImage.heightAnchor.constraint(equalToConstant: 116.0).isActive = true
|
||||||
|
rightImage.widthAnchor.constraint(equalToConstant: 116.0).isActive = true
|
||||||
|
verticalStack = Stack<StackModel>.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)), (view: headline, model: StackItemModel(horizontalAlignment: .leading)), (view: body, model: StackItemModel(horizontalAlignment: .leading)), (view: body2, model: StackItemModel(horizontalAlignment: .leading)), (view: link, model: StackItemModel(spacing: 16, horizontalAlignment: .leading))], axis: .vertical, spacing: 0)
|
||||||
|
|
||||||
|
stack = Stack<StackModel>.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading)), (view: rightImage, model: StackItemModel(verticalAlignment: .center))], axis: .horizontal)
|
||||||
|
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 setupView() {
|
||||||
|
super.setupView()
|
||||||
|
addMolecule(stack)
|
||||||
|
stack.restack()
|
||||||
|
verticalStack.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? ListDeviceComplexLinkMediumModel else { return }
|
||||||
|
verticalStack.updateContainedMolecules(with: [model.eyebrow, model.headline, model.body, model.body2, model.link], delegateObject, additionalData)
|
||||||
|
rightImage.set(with: model.image, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
return 120
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func reset() {
|
||||||
|
super.reset()
|
||||||
|
eyebrow.styleRegularMicro(true)
|
||||||
|
headline.styleBoldTitleMedium(true)
|
||||||
|
body.styleRegularBodySmall(true)
|
||||||
|
body2.styleRegularBodySmall(true)
|
||||||
|
eyebrow.textColor = .mvmCoolGray6
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
//
|
||||||
|
// ListDeviceComplexLinkMediumModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 21/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
public class ListDeviceComplexLinkMediumModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "listDvcLnkM"
|
||||||
|
public var eyebrow: LabelModel?
|
||||||
|
public var headline: LabelModel?
|
||||||
|
public var body: LabelModel?
|
||||||
|
public var body2: LabelModel?
|
||||||
|
public var link: LinkModel
|
||||||
|
public var image: ImageViewModel
|
||||||
|
|
||||||
|
public init(eyebrow: LabelModel, headline: LabelModel, body: LabelModel, body2: LabelModel, link: LinkModel, image: ImageViewModel) {
|
||||||
|
self.eyebrow = eyebrow
|
||||||
|
self.headline = headline
|
||||||
|
self.body = body
|
||||||
|
self.body2 = body2
|
||||||
|
self.link = link
|
||||||
|
self.image = image
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case eyebrow
|
||||||
|
case headline
|
||||||
|
case body
|
||||||
|
case body2
|
||||||
|
case link
|
||||||
|
case image
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow)
|
||||||
|
headline = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .headline)
|
||||||
|
body = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body)
|
||||||
|
body2 = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body2)
|
||||||
|
link = try typeContainer.decode(LinkModel.self, forKey: .link)
|
||||||
|
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
||||||
|
try super.init(from: decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func encode(to encoder: Encoder) throws {
|
||||||
|
try super.encode(to: encoder)
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
|
try container.encodeIfPresent(eyebrow, forKey: .eyebrow)
|
||||||
|
try container.encodeIfPresent(headline, forKey: .headline)
|
||||||
|
try container.encodeIfPresent(body, forKey: .body)
|
||||||
|
try container.encodeIfPresent(body2, forKey: .body2)
|
||||||
|
try container.encode(link, forKey: .link)
|
||||||
|
try container.encode(image, forKey: .image)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
//
|
||||||
|
// ListDeviceComplexLinkSmall.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 24/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
@objcMembers open class ListDeviceComplexLinkSmall: TableViewCell {
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Outlets
|
||||||
|
//-----------------------------------------------------
|
||||||
|
public let eyebrow = Label.createLabelRegularMicro(true)
|
||||||
|
public let headline = Label.createLabelBoldTitleMedium(true)
|
||||||
|
public let body = Label.createLabelRegularBodySmall(true)
|
||||||
|
public let body2 = Label.createLabelRegularBodySmall(true)
|
||||||
|
public let link = Link()
|
||||||
|
public let rightImage = MFLoadImageView()
|
||||||
|
let verticalStack: Stack<StackModel>
|
||||||
|
public let stack: Stack<StackModel>
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//------------------------------------------------------
|
||||||
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
rightImage.addSizeConstraintsForAspectRatio = true
|
||||||
|
rightImage.heightAnchor.constraint(equalToConstant: 71.0).isActive = true
|
||||||
|
rightImage.widthAnchor.constraint(equalToConstant: 71.0).isActive = true
|
||||||
|
verticalStack = Stack<StackModel>.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)), (view: headline, model: StackItemModel(horizontalAlignment: .leading)), (view: body, model: StackItemModel(horizontalAlignment: .leading)), (view: body2, model: StackItemModel(horizontalAlignment: .leading)), (view: link, model: StackItemModel(spacing: 16, horizontalAlignment: .leading))], axis: .vertical, spacing: 0)
|
||||||
|
|
||||||
|
stack = Stack<StackModel>.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading)), (view: rightImage, model: StackItemModel(verticalAlignment: .center))], axis: .horizontal)
|
||||||
|
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 setupView() {
|
||||||
|
super.setupView()
|
||||||
|
addMolecule(stack)
|
||||||
|
stack.restack()
|
||||||
|
verticalStack.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? ListDeviceComplexLinkSmallModel else { return }
|
||||||
|
verticalStack.updateContainedMolecules(with: [model.eyebrow, model.headline, model.body, model.body2, model.link], delegateObject, additionalData)
|
||||||
|
rightImage.set(with: model.image, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
return 120
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func reset() {
|
||||||
|
super.reset()
|
||||||
|
eyebrow.styleRegularMicro(true)
|
||||||
|
headline.styleBoldTitleMedium(true)
|
||||||
|
body.styleRegularBodySmall(true)
|
||||||
|
body2.styleRegularBodySmall(true)
|
||||||
|
eyebrow.textColor = .mvmCoolGray6
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
//
|
||||||
|
// ListDeviceComplexLinkSmallModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 24/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
public class ListDeviceComplexLinkSmallModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "listDvcLnkS"
|
||||||
|
public var eyebrow: LabelModel?
|
||||||
|
public var headline: LabelModel?
|
||||||
|
public var body: LabelModel?
|
||||||
|
public var body2: LabelModel?
|
||||||
|
public var link: LinkModel
|
||||||
|
public var image: ImageViewModel
|
||||||
|
|
||||||
|
public init(eyebrow: LabelModel, headline: LabelModel, body: LabelModel, body2: LabelModel, link: LinkModel, image: ImageViewModel) {
|
||||||
|
self.eyebrow = eyebrow
|
||||||
|
self.headline = headline
|
||||||
|
self.body = body
|
||||||
|
self.body2 = body2
|
||||||
|
self.link = link
|
||||||
|
self.image = image
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case eyebrow
|
||||||
|
case headline
|
||||||
|
case body
|
||||||
|
case body2
|
||||||
|
case link
|
||||||
|
case image
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow)
|
||||||
|
headline = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .headline)
|
||||||
|
body = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body)
|
||||||
|
body2 = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body2)
|
||||||
|
link = try typeContainer.decode(LinkModel.self, forKey: .link)
|
||||||
|
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
||||||
|
try super.init(from: decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func encode(to encoder: Encoder) throws {
|
||||||
|
try super.encode(to: encoder)
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
|
try container.encodeIfPresent(eyebrow, forKey: .eyebrow)
|
||||||
|
try container.encodeIfPresent(headline, forKey: .headline)
|
||||||
|
try container.encodeIfPresent(body, forKey: .body)
|
||||||
|
try container.encodeIfPresent(body2, forKey: .body2)
|
||||||
|
try container.encode(link, forKey: .link)
|
||||||
|
try container.encode(image, forKey: .image)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// ListLeftVariableCheckboxBodyText.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 14/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers open class ListLeftVariableCheckboxBodyText: TableViewCell {
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Outlets
|
||||||
|
//-----------------------------------------------------
|
||||||
|
public let checkbox = Checkbox(frame: .zero)
|
||||||
|
public var headlineBody = HeadlineBody()
|
||||||
|
public var stack: Stack<StackModel>
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//-----------------------------------------------------
|
||||||
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
stack = Stack<StackModel>.createStack(with: [(view: checkbox, model: StackItemModel(horizontalAlignment: .fill)),
|
||||||
|
(view: headlineBody, model: StackItemModel(horizontalAlignment: .leading))],
|
||||||
|
axis: .horizontal)
|
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
public required init?(coder aDecoder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - View Lifecycle
|
||||||
|
//-----------------------------------------------------
|
||||||
|
override open func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
addMolecule(stack)
|
||||||
|
stack.restack()
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------
|
||||||
|
// MARK: - Molecule
|
||||||
|
//----------------------------------------------------
|
||||||
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
guard let model = model as? ListLeftVariableCheckboxBodyTextModel else { return }
|
||||||
|
checkbox.set(with: model.checkbox, delegateObject, additionalData)
|
||||||
|
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
return 90
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// ListLeftVariableCheckboxBodyTextModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Lekshmi S on 14/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
open class ListLeftVariableCheckboxBodyTextModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public static var identifier: String = "listLVCBBdy"
|
||||||
|
public var checkbox: CheckboxModel
|
||||||
|
public var headlineBody: HeadlineBodyModel
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializer
|
||||||
|
//--------------------------------------------------
|
||||||
|
public init(checkbox: CheckboxModel, headlineBody: HeadlineBodyModel) {
|
||||||
|
self.checkbox = checkbox
|
||||||
|
self.headlineBody = headlineBody
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
|
headlineBody.style = .item
|
||||||
|
if let headline = headlineBody.headline {
|
||||||
|
headline.hero = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Keys
|
||||||
|
//--------------------------------------------------
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case headlineBody
|
||||||
|
case checkbox
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// 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)
|
||||||
|
checkbox = try typeContainer.decode(CheckboxModel.self, forKey: .checkbox)
|
||||||
|
try super.init(from: decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func encode(to encoder: Encoder) throws {
|
||||||
|
try super.encode(to: encoder)
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
|
try container.encode(headlineBody, forKey: .headlineBody)
|
||||||
|
try container.encode(checkbox, forKey: .checkbox)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -71,9 +71,6 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
public override func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||||
|
radioButton.tapAction()
|
||||||
if radioButton.isEnabled {
|
|
||||||
radioButton.tapAction()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,24 +40,18 @@ import Foundation
|
|||||||
override open func setupView() {
|
override open func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
addMolecule(stack)
|
addMolecule(stack)
|
||||||
|
stack.restack()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?){
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?){
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
guard let model = model as? ListOneColumnFullWidthTextAllTextAndLinksModel else { return }
|
guard let model = model as? ListOneColumnFullWidthTextAllTextAndLinksModel else { return }
|
||||||
eyebrow.setOptional(with: model.eyebrow, delegateObject, additionalData)
|
stack.updateContainedMolecules(with: [model.eyebrow,
|
||||||
headline.setOptional(with: model.headline, delegateObject, additionalData)
|
model.headline,
|
||||||
subHeadline.setOptional(with: model.subHeadline, delegateObject, additionalData)
|
model.subHeadline,
|
||||||
body.setOptional(with: model.body, delegateObject, additionalData)
|
model.body,
|
||||||
link.setOptional(with: model.link, delegateObject, additionalData)
|
model.link],
|
||||||
|
delegateObject, additionalData)
|
||||||
// Hide labels if neeeded.
|
|
||||||
stack.stackModel?.molecules[0].gone = !eyebrow.hasText
|
|
||||||
stack.stackModel?.molecules[1].gone = !headline.hasText
|
|
||||||
stack.stackModel?.molecules[2].gone = !subHeadline.hasText
|
|
||||||
stack.stackModel?.molecules[3].gone = !body.hasText
|
|
||||||
stack.stackModel?.molecules[4].gone = (link.titleLabel?.text?.count ?? 0) == 0
|
|
||||||
stack.restack()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
@objcMembers open class ListRVWheel: TableViewCell {
|
@objcMembers open class ListRVWheel: TableViewCell {
|
||||||
let wheel = GraphView(frame: .zero)
|
let wheel = Wheel(frame: .zero)
|
||||||
let leftLabel = Label.commonLabelB1(true)
|
let leftLabel = Label.commonLabelB1(true)
|
||||||
let rightLabel = Label.commonLabelB2(true)
|
let rightLabel = Label.commonLabelB2(true)
|
||||||
var stack: Stack<StackModel>
|
var stack: Stack<StackModel>
|
||||||
|
|||||||
@ -11,9 +11,9 @@ public class ListRVWheelModel: ListItemModel, MoleculeModelProtocol {
|
|||||||
public static var identifier: String = "listRVWheel"
|
public static var identifier: String = "listRVWheel"
|
||||||
public var leftLabel: LabelModel
|
public var leftLabel: LabelModel
|
||||||
public var rightLabel: LabelModel
|
public var rightLabel: LabelModel
|
||||||
public var wheel : CircleProgressModel
|
public var wheel: WheelModel
|
||||||
|
|
||||||
public init(leftLabel: LabelModel, rightLabel: LabelModel, wheel: CircleProgressModel) {
|
public init(leftLabel: LabelModel, rightLabel: LabelModel, wheel: WheelModel) {
|
||||||
self.leftLabel = leftLabel
|
self.leftLabel = leftLabel
|
||||||
self.rightLabel = rightLabel
|
self.rightLabel = rightLabel
|
||||||
self.wheel = wheel
|
self.wheel = wheel
|
||||||
@ -37,7 +37,7 @@ public class ListRVWheelModel: ListItemModel, MoleculeModelProtocol {
|
|||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel)
|
leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel)
|
||||||
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
|
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
|
||||||
wheel = try typeContainer.decodeIfPresent(CircleProgressModel.self, forKey: .wheel) ?? CircleProgressModel()
|
wheel = try typeContainer.decodeIfPresent(WheelModel.self, forKey: .wheel) ?? WheelModel()
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,82 @@
|
|||||||
|
//
|
||||||
|
// ListRightVariablePriceChangeAllTextAndLinks.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kruthika KP on 13/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers open class ListRightVariablePriceChangeAllTextAndLinks: TableViewCell {
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Outlets
|
||||||
|
//-----------------------------------------------------
|
||||||
|
public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero)
|
||||||
|
public let arrow = Arrow(frame: .zero)
|
||||||
|
public let rightLabel = Label.commonLabelB2(true)
|
||||||
|
private let stack: Stack<StackModel>
|
||||||
|
private let arrowStackItem: StackItem
|
||||||
|
private let rightLabelStackItem: StackItem
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//-----------------------------------------------------
|
||||||
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .leading),
|
||||||
|
StackItemModel(horizontalAlignment: .fill),
|
||||||
|
StackItemModel(spacing: 6, horizontalAlignment: .fill)],
|
||||||
|
axis: .horizontal)
|
||||||
|
arrowStackItem = StackItem(andContain: arrow)
|
||||||
|
rightLabelStackItem = StackItem(andContain: rightLabel)
|
||||||
|
let stackItems = [StackItem(andContain: eyebrowHeadlineBodyLink), arrowStackItem, rightLabelStackItem]
|
||||||
|
stack = Stack<StackModel>(with: stackModel, stackItems: stackItems)
|
||||||
|
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 alignAccessoryToHero() -> CGPoint? {
|
||||||
|
let heroCenter = super.alignAccessoryToHero()
|
||||||
|
|
||||||
|
// Aligns the center of the right side items to the headline.
|
||||||
|
if let heroCenter = heroCenter {
|
||||||
|
let convertedPoint = stack.convert(heroCenter, from: self)
|
||||||
|
arrowStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - stack.bounds.midY
|
||||||
|
rightLabelStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - stack.bounds.midY
|
||||||
|
}
|
||||||
|
return heroCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
|
||||||
|
rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal)
|
||||||
|
rightLabel.numberOfLines = 1
|
||||||
|
|
||||||
|
arrow.pinHeightAndWidth()
|
||||||
|
|
||||||
|
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? ListRightVariablePriceChangeAllTextAndLinksModel else { return }
|
||||||
|
eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData)
|
||||||
|
rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
|
||||||
|
arrow.set(with: model.arrow, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
return 121
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// ListRightVariablePriceChangeAllTextAndLinksModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kruthika KP on 13/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class ListRightVariablePriceChangeAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "listRVArwAll"
|
||||||
|
public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel
|
||||||
|
public var rightLabel: LabelModel
|
||||||
|
public var arrow: ArrowModel
|
||||||
|
|
||||||
|
public init(eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel, rightLabel: LabelModel, arrow: ArrowModel) {
|
||||||
|
self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink
|
||||||
|
self.rightLabel = rightLabel
|
||||||
|
self.arrow = arrow
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case eyebrowHeadlineBodyLink
|
||||||
|
case rightLabel
|
||||||
|
case arrow
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink)
|
||||||
|
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
|
||||||
|
arrow = try typeContainer.decode(ArrowModel.self, forKey: .arrow)
|
||||||
|
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(eyebrowHeadlineBodyLink, forKey: .eyebrowHeadlineBodyLink)
|
||||||
|
try container.encode(rightLabel, forKey: .rightLabel)
|
||||||
|
try container.encode(arrow, forKey: .arrow)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
//
|
||||||
|
// ListRightVariablePriceChangeBodyText.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Dhamodaram Nandi on 13/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
@objcMembers open class ListRightVariablePriceChangeBodyText: TableViewCell {
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Outlets
|
||||||
|
//-----------------------------------------------------
|
||||||
|
private let stack: Stack<StackModel>
|
||||||
|
public let headlineBody = HeadlineBody(frame: .zero)
|
||||||
|
public let arrow = Arrow(frame: .zero)
|
||||||
|
public let rightLabel = Label.commonLabelB2(true)
|
||||||
|
let arrowAndRightLabelStack: Stack<StackModel>
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - Initializers
|
||||||
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
arrowAndRightLabelStack = Stack<StackModel>.createStack(with: [(view: arrow, model: StackItemModel(horizontalAlignment: .fill)),
|
||||||
|
(view: rightLabel, model: StackItemModel(horizontalAlignment: .fill))],
|
||||||
|
axis: .horizontal, spacing: 6)
|
||||||
|
stack = Stack<StackModel>.createStack(with: [(view: headlineBody, model: StackItemModel(horizontalAlignment: .leading)),
|
||||||
|
(view: arrowAndRightLabelStack, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .leading))],
|
||||||
|
axis: .horizontal)
|
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
public required init?(coder aDecoder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - View Lifecycle
|
||||||
|
//-----------------------------------------------------
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
headlineBody.styleListItem()
|
||||||
|
|
||||||
|
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
|
||||||
|
rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal)
|
||||||
|
rightLabel.numberOfLines = 1
|
||||||
|
|
||||||
|
arrow.pinHeightAndWidth()
|
||||||
|
addMolecule(stack)
|
||||||
|
stack.restack()
|
||||||
|
arrowAndRightLabelStack.restack()
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
guard let model = model as? ListRightVariablePriceChangeBodyTextModel else { return }
|
||||||
|
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
|
||||||
|
rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
|
||||||
|
arrow.set(with: model.arrow, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
return 80
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func reset() {
|
||||||
|
super.reset()
|
||||||
|
headlineBody.styleListItem()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// ListRightVariablePriceChangeBodyTextModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Dhamodaram Nandi on 13/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
public class ListRightVariablePriceChangeBodyTextModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "listRVArwBdy"
|
||||||
|
public var headlineBody: HeadlineBodyModel
|
||||||
|
public var rightLabel: LabelModel
|
||||||
|
public var arrow: ArrowModel
|
||||||
|
|
||||||
|
public init(headlineBody: HeadlineBodyModel,rightLabel: LabelModel,arrow: ArrowModel) {
|
||||||
|
self.headlineBody = headlineBody
|
||||||
|
self.rightLabel = rightLabel
|
||||||
|
self.arrow = arrow
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defaults to set
|
||||||
|
public override func setDefaults() {
|
||||||
|
super.setDefaults()
|
||||||
|
if let headline = headlineBody.headline {
|
||||||
|
headline.hero = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case headlineBody
|
||||||
|
case rightLabel
|
||||||
|
case arrow
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody)
|
||||||
|
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
|
||||||
|
arrow = try typeContainer.decode(ArrowModel.self, forKey: .arrow)
|
||||||
|
try super.init(from: decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func encode(to encoder: Encoder) throws {
|
||||||
|
try super.encode(to: encoder)
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
|
try container.encode(headlineBody, forKey: .headlineBody)
|
||||||
|
try container.encode(rightLabel, forKey: .rightLabel)
|
||||||
|
try container.encode(arrow, forKey: .arrow)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
//
|
||||||
|
// ListThreeColumnDataUsage.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kruthika KP on 20/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers open class ListThreeColumnDataUsage: TableViewCell {
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// MARK: - Outlets
|
||||||
|
//-------------------------------------------------------
|
||||||
|
public let leftLabel = Label.createLabelRegularBodySmall(true)
|
||||||
|
public let centerLabel = Label.createLabelRegularBodySmall(true)
|
||||||
|
public let rightLabel = Label.createLabelRegularBodySmall(true)
|
||||||
|
var stack: Stack<StackModel>
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//------------------------------------------------------
|
||||||
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
stack = Stack<StackModel>.createStack(with: [(view: leftLabel, model: StackItemModel(percent: 40, horizontalAlignment: .leading)),
|
||||||
|
(view: centerLabel, model: StackItemModel(percent: 37, horizontalAlignment: .leading)),
|
||||||
|
(view: rightLabel, model: StackItemModel(percent: 23, horizontalAlignment: .leading))],
|
||||||
|
axis: .horizontal)
|
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
public required init?(coder aDecoder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
addMolecule(stack)
|
||||||
|
stack.restack()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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? ListThreeColumnDataUsageModel else { return }
|
||||||
|
leftLabel.set(with: model.leftLabel, delegateObject, additionalData)
|
||||||
|
centerLabel.set(with: model.centerLabel, delegateObject, additionalData)
|
||||||
|
rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||||
|
return 121
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func reset() {
|
||||||
|
super.reset()
|
||||||
|
leftLabel.styleRegularBodySmall(true)
|
||||||
|
centerLabel.styleRegularBodySmall(true)
|
||||||
|
rightLabel.styleRegularBodySmall(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// ListThreeColumnDataUsageModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kruthika KP on 20/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class ListThreeColumnDataUsageModel: ListItemModel, MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "list3CDataUsg"
|
||||||
|
public var leftLabel: LabelModel
|
||||||
|
public var centerLabel: LabelModel
|
||||||
|
public var rightLabel: LabelModel
|
||||||
|
|
||||||
|
public init(leftLabel:LabelModel, centerLabel:LabelModel, rightLabel:LabelModel) {
|
||||||
|
self.leftLabel = leftLabel
|
||||||
|
self.centerLabel = centerLabel
|
||||||
|
self.rightLabel = rightLabel
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case leftLabel
|
||||||
|
case centerLabel
|
||||||
|
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)
|
||||||
|
centerLabel = try typeContainer.decode(LabelModel.self, forKey: .centerLabel)
|
||||||
|
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(centerLabel, forKey: .centerLabel)
|
||||||
|
try container.encode(rightLabel, forKey: .rightLabel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ import Foundation
|
|||||||
for item in model.sections {
|
for item in model.sections {
|
||||||
stackItems.append(MoleculeStackItemModel(with: item))
|
stackItems.append(MoleculeStackItemModel(with: item))
|
||||||
}
|
}
|
||||||
let stack = MoleculeStackModel(molecules: stackItems)
|
let stack = StackModel(molecules: stackItems)
|
||||||
stack.verticalAlignment = .fill
|
stack.verticalAlignment = .fill
|
||||||
colorLablesStack.set(with: stack, delegateObject, additionalData)
|
colorLablesStack.set(with: stack, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,47 +9,24 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class FooterModel: MoleculeContainerModel, MoleculeModelProtocol {
|
@objcMembers public class FooterModel: MoleculeContainerModel {
|
||||||
public static var identifier: String = "footer"
|
public override class var identifier: String {
|
||||||
public var backgroundColor: Color?
|
return "footer"
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
|
||||||
case moleculeName
|
|
||||||
case backgroundColor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defaults to set
|
/// Defaults to set
|
||||||
func setDefaults() {
|
public override func setDefaults() {
|
||||||
if useHorizontalMargins == nil {
|
if useHorizontalMargins == nil {
|
||||||
useHorizontalMargins = true
|
useHorizontalMargins = true
|
||||||
}
|
}
|
||||||
if useVerticalMargins == nil {
|
if useVerticalMargins == nil {
|
||||||
useVerticalMargins = true
|
useVerticalMargins = true
|
||||||
}
|
}
|
||||||
if topMarginPadding == nil {
|
if topPadding == nil {
|
||||||
topMarginPadding = PaddingDefaultVerticalSpacing
|
topPadding = PaddingDefaultVerticalSpacing
|
||||||
}
|
}
|
||||||
if bottomMarginPadding == nil {
|
if bottomPadding == nil {
|
||||||
bottomMarginPadding = PaddingDefaultVerticalSpacing
|
bottomPadding = PaddingDefaultVerticalSpacing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override init(with moleculeModel: MoleculeModelProtocol) {
|
|
||||||
super.init(with: moleculeModel)
|
|
||||||
setDefaults()
|
|
||||||
}
|
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
|
||||||
try super.init(from: decoder)
|
|
||||||
setDefaults()
|
|
||||||
}
|
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
|
||||||
try super.encode(to: encoder)
|
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
|
||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,18 +18,18 @@ import Foundation
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Defaults to set
|
/// Defaults to set
|
||||||
public func setDefaults() {
|
public override func setDefaults() {
|
||||||
if useHorizontalMargins == nil {
|
if useHorizontalMargins == nil {
|
||||||
useHorizontalMargins = true
|
useHorizontalMargins = true
|
||||||
}
|
}
|
||||||
if useVerticalMargins == nil {
|
if useVerticalMargins == nil {
|
||||||
useVerticalMargins = true
|
useVerticalMargins = true
|
||||||
}
|
}
|
||||||
if topMarginPadding == nil {
|
if topPadding == nil {
|
||||||
topMarginPadding = PaddingDefaultVerticalSpacing
|
topPadding = PaddingDefaultVerticalSpacing
|
||||||
}
|
}
|
||||||
if bottomMarginPadding == nil {
|
if bottomPadding == nil {
|
||||||
bottomMarginPadding = PaddingDefaultVerticalSpacing
|
bottomPadding = PaddingDefaultVerticalSpacing
|
||||||
}
|
}
|
||||||
if line == nil {
|
if line == nil {
|
||||||
line = LineModel(type: .heavy)
|
line = LineModel(type: .heavy)
|
||||||
@ -38,7 +38,6 @@ import Foundation
|
|||||||
|
|
||||||
public override init() {
|
public override init() {
|
||||||
super.init()
|
super.init()
|
||||||
setDefaults()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
@ -46,7 +45,6 @@ import Foundation
|
|||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
setDefaults()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
|
|||||||
320
MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift
Normal file
320
MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
//
|
||||||
|
// Tabs.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Ryan on 2/7/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objc public protocol TabsDelegate {
|
||||||
|
func shouldSelectItem(_ indexPath: IndexPath, tabs: Tabs) -> Bool
|
||||||
|
func didSelectItem(_ indexPath: IndexPath, tabs: Tabs)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objcMembers open class Tabs: View, MVMCoreUIViewConstrainingProtocol {
|
||||||
|
|
||||||
|
public var tabsModel: TabsModel? {
|
||||||
|
get { return model as? TabsModel }
|
||||||
|
}
|
||||||
|
|
||||||
|
var delegateObject: MVMCoreUIDelegateObject?
|
||||||
|
var additionalData: [AnyHashable: Any]?
|
||||||
|
|
||||||
|
let layout = UICollectionViewFlowLayout()
|
||||||
|
public var collectionView: UICollectionView?
|
||||||
|
|
||||||
|
let bottomScrollView = UIScrollView(frame: .zero)
|
||||||
|
let bottomContentView = View()
|
||||||
|
let bottomLine = View()
|
||||||
|
var bottomLineLeftConstraint: NSLayoutConstraint?
|
||||||
|
var bottomLineWidthConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
|
private var widthLabel = Label()
|
||||||
|
|
||||||
|
//delegate
|
||||||
|
weak public var delegate: TabsDelegate?
|
||||||
|
|
||||||
|
//control var
|
||||||
|
public var heightConstraint: NSLayoutConstraint?
|
||||||
|
public var selectedIndex: Int = 0
|
||||||
|
public var paddingBeforeFirstTab: Bool = true
|
||||||
|
|
||||||
|
//constant
|
||||||
|
let TabCellId = "TabCell"
|
||||||
|
public let sectionPadding: CGFloat = 20.0
|
||||||
|
public let cellSpacing: CGFloat = 34.0
|
||||||
|
public let cellHeight: CGFloat = 34.0
|
||||||
|
public let bottomLineHeight: CGFloat = 4.0
|
||||||
|
public let bottomLineWidth: CGFloat = 32.0
|
||||||
|
public let tabsHeight: CGFloat = 38.0
|
||||||
|
public let bottomLineMovingTime: TimeInterval = 0.2
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// MARK:- Layout Views
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
open override func reset() {
|
||||||
|
super.reset()
|
||||||
|
heightConstraint?.constant = tabsHeight
|
||||||
|
selectedIndex = 0
|
||||||
|
paddingBeforeFirstTab = true
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func updateView(_ size: CGFloat) {
|
||||||
|
super.updateView(size)
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
backgroundColor = .white
|
||||||
|
setupCollectionView()
|
||||||
|
setupBottomLine()
|
||||||
|
setupConstraints()
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupCollectionView () {
|
||||||
|
layout.scrollDirection = .horizontal
|
||||||
|
layout.minimumLineSpacing = cellSpacing
|
||||||
|
|
||||||
|
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
|
||||||
|
collectionView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
collectionView.register(TabItemCell.self, forCellWithReuseIdentifier: TabCellId)
|
||||||
|
collectionView.backgroundColor = .clear
|
||||||
|
collectionView.showsVerticalScrollIndicator = false
|
||||||
|
collectionView.showsHorizontalScrollIndicator = false
|
||||||
|
collectionView.dataSource = self
|
||||||
|
collectionView.delegate = self
|
||||||
|
addSubview(collectionView)
|
||||||
|
self.collectionView = collectionView
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupBottomLine() {
|
||||||
|
bottomScrollView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
bottomScrollView.delegate = self
|
||||||
|
addSubview(bottomScrollView)
|
||||||
|
bottomScrollView.addSubview(bottomContentView)
|
||||||
|
bottomLine.backgroundColor = .mvmRed
|
||||||
|
bottomContentView.addSubview(bottomLine)
|
||||||
|
bringSubviewToFront(bottomScrollView)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupConstraints() {
|
||||||
|
//collection view
|
||||||
|
NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView)
|
||||||
|
|
||||||
|
//bottom lines
|
||||||
|
NSLayoutConstraint.constraintPinSubview(bottomScrollView, pinTop: false, pinBottom: true, pinLeft: true, pinRight: true)
|
||||||
|
bottomScrollView.heightAnchor.constraint(equalToConstant: bottomLineHeight).isActive = true
|
||||||
|
NSLayoutConstraint.constraintPinSubview(bottomLine, pinTop: true, pinBottom: true, pinLeft: false, pinRight: false)
|
||||||
|
bottomLine.heightAnchor.constraint(equalToConstant: bottomLineHeight).isActive = true
|
||||||
|
bottomLineLeftConstraint = bottomLine.leftAnchor.constraint(equalTo: bottomContentView.leftAnchor)
|
||||||
|
bottomLineLeftConstraint?.isActive = true
|
||||||
|
bottomLineWidthConstraint = bottomLine.widthAnchor.constraint(equalToConstant: bottomLineWidth)
|
||||||
|
bottomLineWidthConstraint?.isActive = true
|
||||||
|
NSLayoutConstraint.constraintPinSubview(toSuperview: bottomContentView)
|
||||||
|
|
||||||
|
//height
|
||||||
|
heightConstraint = heightAnchor.constraint(equalToConstant: tabsHeight)
|
||||||
|
heightConstraint?.isActive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// MARK:- Control Methods
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
public func pinHeight(_ height: CGFloat) {
|
||||||
|
heightConstraint?.constant = height
|
||||||
|
setNeedsLayout()
|
||||||
|
layoutIfNeeded()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func selectIndex(_ index: Int, animated: Bool) {
|
||||||
|
guard let _ = collectionView, tabsModel?.tabs.count ?? 0 > 0 else {
|
||||||
|
selectedIndex = index
|
||||||
|
return
|
||||||
|
}
|
||||||
|
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||||
|
let currentIndex = self.selectedIndex
|
||||||
|
self.selectedIndex = index
|
||||||
|
self.deselect(indexPath: IndexPath(row: currentIndex, section: 0))
|
||||||
|
self.selectItem(atIndexPath: IndexPath(row: index, section: 0), animated: animated)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public func reloadData() {
|
||||||
|
collectionView?.reloadData()
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// MARK:- Molecule Setup
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
self.delegateObject = delegateObject
|
||||||
|
self.additionalData = additionalData
|
||||||
|
self.selectedIndex = tabsModel?.selectedIndex ?? 0
|
||||||
|
self.bottomLine.backgroundColor = tabsModel?.selectedColor.uiColor
|
||||||
|
reloadData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// MARK:- Collection View Methods
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
extension Tabs: UICollectionViewDataSource {
|
||||||
|
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
|
return tabsModel?.tabs.count ?? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
|
guard let labelModel = tabsModel?.tabs[indexPath.row].label, let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TabCellId, for: indexPath) as? TabItemCell else {
|
||||||
|
return UICollectionViewCell()
|
||||||
|
}
|
||||||
|
cell.updateCell(labelModel: labelModel, indexPath: indexPath, delegateObject: delegateObject, additionalData: additionalData, selected: indexPath.row == selectedIndex, tabsModel: tabsModel)
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Tabs: UICollectionViewDelegateFlowLayout {
|
||||||
|
|
||||||
|
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
|
||||||
|
guard let labelModel = tabsModel?.tabs[indexPath.row].label else {
|
||||||
|
return .zero
|
||||||
|
}
|
||||||
|
return CGSize(width: getLabelWidth(labelModel).width, height: cellHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
//pre calculate the width of the collection cell
|
||||||
|
//when user select tabs, it will reload related collectionview, if we use autosize, it would relayout the width, need to keep the cell width constant.
|
||||||
|
func getLabelWidth(_ labelModel: LabelModel?) -> CGSize {
|
||||||
|
guard let labelModel = labelModel else { return .zero}
|
||||||
|
widthLabel.set(with: labelModel, nil, nil)
|
||||||
|
let cgSize = widthLabel.intrinsicContentSize
|
||||||
|
widthLabel.reset()
|
||||||
|
return cgSize
|
||||||
|
}
|
||||||
|
|
||||||
|
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
|
||||||
|
if !paddingBeforeFirstTab && section == 0 {
|
||||||
|
return .zero
|
||||||
|
} else {
|
||||||
|
return UIEdgeInsets(top: 0, left: sectionPadding, bottom: 0, right: 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
|
||||||
|
return sectionPadding
|
||||||
|
}
|
||||||
|
|
||||||
|
public func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
|
||||||
|
return delegate?.shouldSelectItem(indexPath, tabs: self) ?? true
|
||||||
|
}
|
||||||
|
|
||||||
|
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
|
selectIndex(indexPath.row, animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
|
||||||
|
guard let tabCell = cell as? TabItemCell else { return }
|
||||||
|
if indexPath.row == selectedIndex {
|
||||||
|
moveBottomLine(toIndex: indexPath, animated: false, cell: tabCell)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func deselect(indexPath:IndexPath) {
|
||||||
|
collectionView?.deselectItem(at: indexPath, animated: false)
|
||||||
|
collectionView?.reloadItems(at: [indexPath])
|
||||||
|
}
|
||||||
|
|
||||||
|
func selectItem(atIndexPath indexPath: IndexPath, animated: Bool) {
|
||||||
|
|
||||||
|
guard let collect = collectionView, tabsModel?.tabs.count ?? 0 > 0 else { return }
|
||||||
|
|
||||||
|
collect.selectItem(at: indexPath, animated: animated, scrollPosition: .centeredHorizontally)
|
||||||
|
guard let tabCell = collect.cellForItem(at: indexPath) as? TabItemCell, let tabsModel = self.tabsModel else { return }
|
||||||
|
self.moveBottomLine(toIndex: indexPath, animated: animated, cell: tabCell)
|
||||||
|
tabCell.label.textColor = tabsModel.selectedColor.uiColor
|
||||||
|
tabCell.updateAccessibility(indexPath: indexPath, selected: true, tabsModel: tabsModel)
|
||||||
|
tabCell.setNeedsDisplay()
|
||||||
|
tabCell.setNeedsLayout()
|
||||||
|
tabCell.layoutIfNeeded()
|
||||||
|
self.delegate?.didSelectItem(indexPath, tabs: self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension Tabs: UIScrollViewDelegate {
|
||||||
|
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||||
|
/*bottomScrollview is subview of self, it's not belongs to collectionview.
|
||||||
|
When collectionview is scrolling, bottomScrollView will stay without moving
|
||||||
|
Adding collectionview's offset to bottomScrollView, will make the bottomScrollview looks like scrolling with the selected tab item.
|
||||||
|
*/
|
||||||
|
guard let offsetX = collectionView?.contentOffset.x else { return }
|
||||||
|
bottomScrollView.setContentOffset(CGPoint(x: offsetX, y: bottomScrollView.contentOffset.y), animated: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// MARK:- Bottom Line Methods
|
||||||
|
//-------------------------------------------------
|
||||||
|
extension Tabs {
|
||||||
|
func moveBottomLine(toIndex indexPath: IndexPath, animated: Bool, cell: TabItemCell) {
|
||||||
|
guard let collect = self.collectionView else {return}
|
||||||
|
|
||||||
|
let size = collectionView(collect, layout: layout, sizeForItemAt: indexPath)
|
||||||
|
let barWidth = max(size.width, bottomLineWidth)
|
||||||
|
let animationBlock = {
|
||||||
|
[weak self] in
|
||||||
|
let x = cell.frame.origin.x
|
||||||
|
self?.bottomLineWidthConstraint?.constant = barWidth
|
||||||
|
self?.bottomLineLeftConstraint?.constant = x + (size.width - barWidth) / 2.0
|
||||||
|
self?.bottomContentView.layoutIfNeeded()
|
||||||
|
}
|
||||||
|
if animated {
|
||||||
|
UIView.animate(withDuration: bottomLineMovingTime, animations: animationBlock)
|
||||||
|
} else {
|
||||||
|
animationBlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objcMembers public class TabItemCell: CollectionViewCell {
|
||||||
|
public let label = Label()
|
||||||
|
public var labelModel: LabelModel?
|
||||||
|
|
||||||
|
public override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
contentView.addSubview(label)
|
||||||
|
NSLayoutConstraint.constraintPinSubview(label, pinTop: false, pinBottom: false, pinLeft: true, pinRight: true)
|
||||||
|
label.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
|
||||||
|
label.baselineAdjustment = .alignCenters
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateCell(labelModel: LabelModel, indexPath: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?, selected: Bool, tabsModel: TabsModel?) {
|
||||||
|
label.reset()
|
||||||
|
label.set(with: labelModel, delegateObject, additionalData)
|
||||||
|
self.labelModel = labelModel
|
||||||
|
if selected, let selectedColor = tabsModel?.selectedColor {
|
||||||
|
label.textColor = selectedColor.uiColor
|
||||||
|
}
|
||||||
|
updateAccessibility(indexPath: indexPath, selected: selected, tabsModel: tabsModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateAccessibility(indexPath: IndexPath, selected: Bool, tabsModel: TabsModel?) {
|
||||||
|
//Accessibility
|
||||||
|
isAccessibilityElement = false
|
||||||
|
contentView.isAccessibilityElement = true
|
||||||
|
let accKey = selected ? "toptabbar_tab_selected" : "AccTab"
|
||||||
|
let accLabel = "\(label.text ?? "") \(MVMCoreUIUtility.hardcodedString(withKey: accKey) ?? "")"
|
||||||
|
let accOrder = String(format: MVMCoreUIUtility.hardcodedString(withKey: "AccTabIndex") ?? "", indexPath.row + 1, tabsModel?.tabs.count ?? 0)
|
||||||
|
contentView.accessibilityLabel = "\(accLabel) \(accOrder)"
|
||||||
|
contentView.accessibilityHint = selected ? nil : MVMCoreUIUtility.hardcodedString(withKey: "AccTabHint")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ import UIKit
|
|||||||
public class TabsModel: MoleculeModelProtocol {
|
public class TabsModel: MoleculeModelProtocol {
|
||||||
public static var identifier: String = "tabs"
|
public static var identifier: String = "tabs"
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var tabs: [LabelModel]
|
public var tabs: [TabItemModel]
|
||||||
public var selectedColor = Color(uiColor: .mfTomatoRed())
|
public var selectedColor = Color(uiColor: .mfTomatoRed())
|
||||||
|
|
||||||
// Must be capped to 0...(tabs.count - 1)
|
// Must be capped to 0...(tabs.count - 1)
|
||||||
@ -25,13 +25,13 @@ public class TabsModel: MoleculeModelProtocol {
|
|||||||
case moleculeName
|
case moleculeName
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(with tabs: [LabelModel]) {
|
public init(with tabs: [TabItemModel]) {
|
||||||
self.tabs = tabs
|
self.tabs = tabs
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
tabs = try typeContainer.decode([LabelModel].self, forKey: .tabs)
|
tabs = try typeContainer.decode([TabItemModel].self, forKey: .tabs)
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedColor) {
|
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedColor) {
|
||||||
selectedColor = color
|
selectedColor = color
|
||||||
@ -50,3 +50,33 @@ public class TabsModel: MoleculeModelProtocol {
|
|||||||
try container.encode(selectedIndex, forKey: .selectedIndex)
|
try container.encode(selectedIndex, forKey: .selectedIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class TabItemModel: Codable {
|
||||||
|
var label: LabelModel
|
||||||
|
var action: ActionModelProtocol?
|
||||||
|
|
||||||
|
init(label: LabelModel) {
|
||||||
|
self.label = label
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case label
|
||||||
|
case action
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
label = try typeContainer.decode(LabelModel.self, forKey: .label)
|
||||||
|
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encodeModel(label, forKey: .label)
|
||||||
|
try container.encodeModelIfPresent(action, forKey: .action)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ import Foundation
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
/// Defaults to set
|
/// Defaults to set
|
||||||
open func setDefaults() {
|
open override func setDefaults() {
|
||||||
if useHorizontalMargins == nil {
|
if useHorizontalMargins == nil {
|
||||||
useHorizontalMargins = true
|
useHorizontalMargins = true
|
||||||
}
|
}
|
||||||
@ -54,9 +54,12 @@ import Foundation
|
|||||||
// MARK: - Initializer
|
// MARK: - Initializer
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public override init(horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil, useHorizontalMargins: Bool? = nil, leftPadding: CGFloat? = nil, rightPadding: CGFloat? = nil, useVerticalMargins: Bool? = nil, topPadding: CGFloat? = nil, bottomPadding: CGFloat? = nil) {
|
||||||
|
super.init(horizontalAlignment: horizontalAlignment, verticalAlignment: verticalAlignment, useHorizontalMargins: useHorizontalMargins, leftPadding: leftPadding, rightPadding: rightPadding, useVerticalMargins: useVerticalMargins, topPadding: topPadding, bottomPadding: bottomPadding)
|
||||||
|
}
|
||||||
|
|
||||||
public override init() {
|
public override init() {
|
||||||
super.init()
|
super.init()
|
||||||
setDefaults()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -71,7 +74,6 @@ import Foundation
|
|||||||
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
||||||
style = try typeContainer.decodeIfPresent(String.self, forKey: .style)
|
style = try typeContainer.decodeIfPresent(String.self, forKey: .style)
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
setDefaults()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func encode(to encoder: Encoder) throws {
|
open override func encode(to encoder: Encoder) throws {
|
||||||
|
|||||||
@ -9,49 +9,36 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/// A model for a collection item that is a container for any molecule.
|
/// A model for a collection item that is a container for any molecule.
|
||||||
@objcMembers public class MoleculeCollectionItemModel: MoleculeContainerModel, CollectionItemModelProtocol, MoleculeModelProtocol {
|
@objcMembers public class MoleculeCollectionItemModel: MoleculeContainerModel, CollectionItemModelProtocol {
|
||||||
open class var identifier: String {
|
open override class var identifier: String {
|
||||||
return "collectionItem"
|
return "collectionItem"
|
||||||
}
|
}
|
||||||
public var backgroundColor: Color?
|
|
||||||
|
|
||||||
/// Defaults to set
|
/// Defaults to set
|
||||||
public func setDefaults() {
|
public override func setDefaults() {
|
||||||
if useHorizontalMargins == nil {
|
if useHorizontalMargins == nil {
|
||||||
useHorizontalMargins = true
|
useHorizontalMargins = true
|
||||||
}
|
}
|
||||||
if useVerticalMargins == nil {
|
if useVerticalMargins == nil {
|
||||||
useVerticalMargins = true
|
useVerticalMargins = true
|
||||||
}
|
}
|
||||||
if topMarginPadding == nil {
|
if topPadding == nil {
|
||||||
topMarginPadding = PaddingDefault
|
topPadding = PaddingDefault
|
||||||
}
|
}
|
||||||
if bottomMarginPadding == nil {
|
if bottomPadding == nil {
|
||||||
bottomMarginPadding = PaddingDefault
|
bottomPadding = PaddingDefault
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
|
||||||
case moleculeName
|
|
||||||
case backgroundColor
|
|
||||||
}
|
|
||||||
|
|
||||||
public override init(with moleculeModel: MoleculeModelProtocol) {
|
public override init(with moleculeModel: MoleculeModelProtocol) {
|
||||||
super.init(with: moleculeModel)
|
super.init(with: moleculeModel)
|
||||||
setDefaults()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
setDefaults()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
|
||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,6 +54,6 @@ open class MoleculeCollectionViewCell: CollectionViewCell {
|
|||||||
let height = classType.estimatedHeight(with: model.molecule, delegateObject)
|
let height = classType.estimatedHeight(with: model.molecule, delegateObject)
|
||||||
else { return 100 }
|
else { return 100 }
|
||||||
|
|
||||||
return height + (model.topMarginPadding ?? 0) + (model.bottomMarginPadding ?? 0)
|
return height + (model.topPadding ?? 0) + (model.bottomPadding ?? 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,15 +8,15 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class MoleculeStackItemModel: MoleculeContainerModel, MoleculeModelProtocol, StackItemModelProtocol {
|
@objcMembers public class MoleculeStackItemModel: MoleculeContainerModel, StackItemModelProtocol {
|
||||||
public static var identifier: String = "stackItem"
|
public override class var identifier: String {
|
||||||
public var backgroundColor: Color?
|
return "stackItem"
|
||||||
|
}
|
||||||
public var spacing: CGFloat?
|
public var spacing: CGFloat?
|
||||||
public var percent: Int?
|
public var percent: Int?
|
||||||
public var gone: Bool = false
|
public var gone: Bool = false
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
|
||||||
case spacing
|
case spacing
|
||||||
case percent
|
case percent
|
||||||
case gone
|
case gone
|
||||||
@ -39,7 +39,6 @@ import Foundation
|
|||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
|
||||||
try container.encodeIfPresent(spacing, forKey: .spacing)
|
try container.encodeIfPresent(spacing, forKey: .spacing)
|
||||||
try container.encodeIfPresent(percent, forKey: .percent)
|
try container.encodeIfPresent(percent, forKey: .percent)
|
||||||
try container.encode(gone, forKey: .gone)
|
try container.encode(gone, forKey: .gone)
|
||||||
|
|||||||
@ -24,16 +24,17 @@ import Foundation
|
|||||||
// MARK: - Initializer
|
// MARK: - Initializer
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public convenience init(spacing: CGFloat? = nil, percent: Int? = nil, horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil, gone: Bool? = nil) {
|
public init(spacing: CGFloat? = nil, percent: Int? = nil, horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil, gone: Bool? = nil) {
|
||||||
self.init()
|
|
||||||
|
|
||||||
self.horizontalAlignment = horizontalAlignment
|
|
||||||
self.verticalAlignment = verticalAlignment
|
|
||||||
self.spacing = spacing
|
self.spacing = spacing
|
||||||
self.percent = percent
|
self.percent = percent
|
||||||
|
|
||||||
if let gone = gone {
|
if let gone = gone {
|
||||||
self.gone = gone
|
self.gone = gone
|
||||||
}
|
}
|
||||||
|
super.init(horizontalAlignment: horizontalAlignment, verticalAlignment: verticalAlignment)
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
fatalError("init(from:) has not been implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol StackItemModelProtocol: MoleculeModelProtocol {
|
public protocol StackItemModelProtocol {
|
||||||
var spacing: CGFloat? { get set }
|
var spacing: CGFloat? { get set }
|
||||||
var percent: Int? { get set }
|
var percent: Int? { get set }
|
||||||
var gone: Bool { get set }
|
var gone: Bool { get set }
|
||||||
|
|||||||
@ -24,8 +24,8 @@ public class TabsListItemModel: ListItemModel, MoleculeModelProtocol {
|
|||||||
hideArrow = true
|
hideArrow = true
|
||||||
action = nil
|
action = nil
|
||||||
style = nil
|
style = nil
|
||||||
topMarginPadding = 8
|
topPadding = 8
|
||||||
bottomMarginPadding = 0
|
bottomPadding = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(with tabs: TabsModel, molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]) {
|
public init(with tabs: TabsModel, molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]) {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import UIKit
|
|||||||
var tabsListItemModel: TabsListItemModel? {
|
var tabsListItemModel: TabsListItemModel? {
|
||||||
return listItemModel as? TabsListItemModel
|
return listItemModel as? TabsListItemModel
|
||||||
}
|
}
|
||||||
let tabs = TopTabbar(frame: .zero)
|
let tabs = Tabs(frame: .zero)
|
||||||
var delegateObject: MVMCoreUIDelegateObject?
|
var delegateObject: MVMCoreUIDelegateObject?
|
||||||
var previousTabIndex = 0
|
var previousTabIndex = 0
|
||||||
|
|
||||||
@ -22,7 +22,6 @@ import UIKit
|
|||||||
tabs.paddingBeforeFirstTab = false
|
tabs.paddingBeforeFirstTab = false
|
||||||
tabs.translatesAutoresizingMaskIntoConstraints = false
|
tabs.translatesAutoresizingMaskIntoConstraints = false
|
||||||
tabs.delegate = self
|
tabs.delegate = self
|
||||||
tabs.datasource = self
|
|
||||||
contentView.addSubview(tabs)
|
contentView.addSubview(tabs)
|
||||||
|
|
||||||
NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: tabs, useMargins: true).values))
|
NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: tabs, useMargins: true).values))
|
||||||
@ -39,7 +38,9 @@ import UIKit
|
|||||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
self.delegateObject = delegateObject
|
self.delegateObject = delegateObject
|
||||||
tabs.reloadData()
|
if let tabsModel = tabsListItemModel?.tabs {
|
||||||
|
tabs.set(with: tabsModel, delegateObject, additionalData)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func reset() {
|
public override func reset() {
|
||||||
@ -53,33 +54,22 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TabsTableViewCell: TopTabbarDelegate {
|
extension TabsTableViewCell: TabsDelegate {
|
||||||
public func shouldSelectItem(at index: Int, topTabbar: TopTabbar) -> Bool {
|
public func shouldSelectItem(_ indexPath: IndexPath, tabs: Tabs) -> Bool {
|
||||||
if let model = tabsListItemModel {
|
if let model = tabsListItemModel {
|
||||||
let molecules = model.molecules[topTabbar.selectedIndex]
|
let molecules = model.molecules[tabs.selectedIndex]
|
||||||
delegateObject?.moleculeDelegate?.removeMolecules(molecules, animation: index < tabs.selectedIndex ? .right : .left)
|
delegateObject?.moleculeDelegate?.removeMolecules(molecules, animation: indexPath.row < tabs.selectedIndex ? .right : .left)
|
||||||
}
|
}
|
||||||
previousTabIndex = tabs.selectedIndex
|
previousTabIndex = tabs.selectedIndex
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
public func topTabbar(_ topTabbar: TopTabbar, didSelectItemAt index: Int) {
|
public func didSelectItem(_ indexPath: IndexPath, tabs: Tabs) {
|
||||||
guard let model = tabsListItemModel,
|
let index = indexPath.row
|
||||||
let indexPath = delegateObject?.moleculeDelegate?.getIndexPath(for: model) else { return }
|
if let model = tabsListItemModel, index < model.molecules.count {
|
||||||
let molecules = model.molecules[index]
|
let molecules = model.molecules[index]
|
||||||
delegateObject?.moleculeDelegate?.addMolecules(molecules, indexPath: indexPath, animation: index < previousTabIndex ? .left : .right)
|
delegateObject?.moleculeDelegate?.addMolecules(molecules, indexPath: indexPath, animation: index < previousTabIndex ? .left : .right)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension TabsTableViewCell: TopTabbarDataSource {
|
|
||||||
public func number(ofTopTabbarItems topTabbar: TopTabbar) -> Int {
|
|
||||||
return tabsListItemModel?.tabs.tabs.count ?? 0
|
|
||||||
}
|
|
||||||
|
|
||||||
public func topTabbar(_ topTabbar: TopTabbar, titleForItemAt index: Int) -> String? {
|
|
||||||
guard let title = tabsListItemModel?.tabs.tabs[index].text else {
|
|
||||||
return "Select"
|
|
||||||
}
|
}
|
||||||
return title
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -164,10 +164,12 @@ import UIKit
|
|||||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
guard let model = model as? CornerLabelsModel else { return }
|
guard let model = model as? CornerLabelsModel else { return }
|
||||||
if middleView != nil {
|
if let moleculeModel = model.molecule {
|
||||||
(middleView as? MoleculeViewProtocol)?.set(with: model, delegateObject, additionalData)
|
if middleView != nil {
|
||||||
} else if let moleculeModel = model.molecule, let molecule = MoleculeObjectMapping.shared()?.createMolecule(moleculeModel, delegateObject: delegateObject, additionalData: additionalData) {
|
(middleView as? MoleculeViewProtocol)?.set(with: moleculeModel, delegateObject, additionalData)
|
||||||
addMiddleView(molecule)
|
} else if let molecule = MoleculeObjectMapping.shared()?.createMolecule(moleculeModel, delegateObject: delegateObject, additionalData: additionalData) {
|
||||||
|
addMiddleView(molecule)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
topLeftLabel.setOptional(with: model.topLeftLabel, delegateObject, additionalData)
|
topLeftLabel.setOptional(with: model.topLeftLabel, delegateObject, additionalData)
|
||||||
|
|||||||
@ -8,11 +8,19 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
|
||||||
@objcMembers open class LabelToggle: View {
|
@objcMembers open class LabelToggle: View {
|
||||||
public let label = Label.commonLabelB1(true)
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public let label = Label.createLabelBoldBodySmall(true)
|
||||||
public let toggle = Toggle()
|
public let toggle = Toggle()
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - MVMCoreViewProtocol
|
// MARK: - MVMCoreViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func updateView(_ size: CGFloat) {
|
open override func updateView(_ size: CGFloat) {
|
||||||
super.updateView(size)
|
super.updateView(size)
|
||||||
label.updateView(size)
|
label.updateView(size)
|
||||||
@ -21,28 +29,26 @@ import UIKit
|
|||||||
|
|
||||||
open override func setupView() {
|
open override func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
guard toggle.superview == nil else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
addSubview(label)
|
addSubview(label)
|
||||||
addSubview(toggle)
|
addSubview(toggle)
|
||||||
label.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical)
|
label.setContentHuggingPriority(.required, for: .vertical)
|
||||||
NSLayoutConstraint.pinViews(leftView: label, rightView: toggle, alignTop: false)
|
NSLayoutConstraint.pinViews(leftView: label, rightView: toggle, alignTop: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK:- MoleculeViewProtocol
|
|
||||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
guard let model = model as? LabelToggleModel,
|
guard let model = model as? LabelToggleModel,
|
||||||
let toggleHeight = Toggle.estimatedHeight(with: model.toggle, delegateObject),
|
let toggleHeight = Toggle.estimatedHeight(with: model.toggle, delegateObject),
|
||||||
let labelHeight = Label.estimatedHeight(with: model.label, delegateObject) else { return nil }
|
let labelHeight = Label.estimatedHeight(with: model.label, delegateObject)
|
||||||
|
else { return nil }
|
||||||
|
|
||||||
return max(toggleHeight, labelHeight)
|
return max(toggleHeight, labelHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
guard let labelToggleModel = model as? LabelToggleModel else {
|
|
||||||
return
|
guard let labelToggleModel = model as? LabelToggleModel else { return }
|
||||||
}
|
|
||||||
label.set(with: labelToggleModel.label, delegateObject, additionalData)
|
label.set(with: labelToggleModel.label, delegateObject, additionalData)
|
||||||
toggle.set(with: labelToggleModel.toggle, delegateObject, additionalData)
|
toggle.set(with: labelToggleModel.toggle, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
@ -52,6 +58,6 @@ import UIKit
|
|||||||
super.reset()
|
super.reset()
|
||||||
label.reset()
|
label.reset()
|
||||||
toggle.reset()
|
toggle.reset()
|
||||||
label.styleB1(true)
|
label.styleBoldBodySmall(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,17 +10,16 @@ import Foundation
|
|||||||
|
|
||||||
public protocol NavigationItemModelProtocol {
|
public protocol NavigationItemModelProtocol {
|
||||||
var title: String? { get set }
|
var title: String? { get set }
|
||||||
var titleView: MoleculeModelProtocol? { get set }
|
|
||||||
var hidden: Bool { get set }
|
var hidden: Bool { get set }
|
||||||
var backgroundColor: Color? { get set }
|
var backgroundColor: Color? { get set }
|
||||||
var transparent: Bool { get set }
|
var translucent: Bool { get set }
|
||||||
var tintColor: Color { get set }
|
var tintColor: Color { get set }
|
||||||
var line: LineModel? { get set }
|
var line: LineModel? { get set }
|
||||||
var systemBackButton: Bool { get set }
|
var showLeftPanelButton: Bool { get set }
|
||||||
var showLeftPanelButton: Bool? { get set }
|
var showRightPanelButton: Bool { get set }
|
||||||
var showRightPanelButton: Bool? { get set }
|
var backButton: NavigationItemButtonModel? { get set }
|
||||||
var additionalLeftItems: [NavigationItemButtonModel]? { get set }
|
var additionalLeftButtons: [NavigationItemButtonModel]? { get set }
|
||||||
var additionalRightItems: [NavigationItemButtonModel]? { get set }
|
var additionalRightButtons: [NavigationItemButtonModel]? { get set }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NavigationItemButtonModel: Codable {
|
public class NavigationItemButtonModel: Codable {
|
||||||
@ -52,74 +51,73 @@ public class NavigationItemButtonModel: Codable {
|
|||||||
|
|
||||||
public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtocol {
|
public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtocol {
|
||||||
public class var identifier: String {
|
public class var identifier: String {
|
||||||
return "navigationItem"
|
return "navigationBar"
|
||||||
}
|
}
|
||||||
|
|
||||||
public var title: String?
|
public var title: String?
|
||||||
public var titleView: MoleculeModelProtocol?
|
|
||||||
public var hidden: Bool
|
public var hidden: Bool
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var transparent: Bool
|
public var translucent: Bool
|
||||||
public var tintColor: Color
|
public var tintColor: Color
|
||||||
public var line: LineModel?
|
public var line: LineModel?
|
||||||
public var systemBackButton = false
|
public var showLeftPanelButton: Bool
|
||||||
public var showLeftPanelButton: Bool?
|
public var showRightPanelButton: Bool
|
||||||
public var showRightPanelButton: Bool?
|
public var backButton: NavigationItemButtonModel?
|
||||||
public var additionalLeftItems: [NavigationItemButtonModel]?
|
public var additionalLeftButtons: [NavigationItemButtonModel]?
|
||||||
public var additionalRightItems: [NavigationItemButtonModel]?
|
public var additionalRightButtons: [NavigationItemButtonModel]?
|
||||||
|
|
||||||
init() {
|
public init() {
|
||||||
hidden = false
|
hidden = false
|
||||||
transparent = false
|
translucent = false
|
||||||
backgroundColor = Color(uiColor: .white)
|
backgroundColor = Color(uiColor: .white)
|
||||||
tintColor = Color(uiColor: .black)
|
tintColor = Color(uiColor: .black)
|
||||||
line = LineModel(type: .standard)
|
line = LineModel(type: .standard)
|
||||||
|
showLeftPanelButton = true
|
||||||
|
showRightPanelButton = true
|
||||||
|
backButton = NavigationItemButtonModel(with: "back", action: ActionBackModel())
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case title
|
case title
|
||||||
case titleView
|
|
||||||
case hidden
|
case hidden
|
||||||
case backgroundColor
|
case backgroundColor
|
||||||
case transparent
|
case translucent
|
||||||
case tintColor
|
case tintColor
|
||||||
case line
|
case line
|
||||||
case systemBackButton
|
case backButton
|
||||||
case showLeftPanelButton
|
case showLeftPanelButton
|
||||||
case showRightPanelButton
|
case showRightPanelButton
|
||||||
case additionalLeftItems
|
case additionalLeftButtons
|
||||||
case additionalRightItems
|
case additionalRightButtons
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
|
title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
|
||||||
titleView = try typeContainer.decodeModelIfPresent(codingKey: .titleView)
|
|
||||||
hidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidden) ?? false
|
hidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidden) ?? false
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) ?? Color(uiColor: .white)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) ?? Color(uiColor: .white)
|
||||||
transparent = try typeContainer.decodeIfPresent(Bool.self, forKey: .transparent) ?? false
|
translucent = try typeContainer.decodeIfPresent(Bool.self, forKey: .translucent) ?? false
|
||||||
tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .black)
|
tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .black)
|
||||||
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
||||||
systemBackButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .systemBackButton) ?? false
|
backButton = try typeContainer.decodeIfPresent(NavigationItemButtonModel.self, forKey: .backButton) ?? NavigationItemButtonModel(with: "back", action: ActionBackModel())
|
||||||
showLeftPanelButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .showLeftPanelButton)
|
showLeftPanelButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .showLeftPanelButton) ?? true
|
||||||
showRightPanelButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .showRightPanelButton)
|
showRightPanelButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .showRightPanelButton) ?? true
|
||||||
additionalLeftItems = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalLeftItems)
|
additionalLeftButtons = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalLeftButtons)
|
||||||
additionalRightItems = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalRightItems)
|
additionalRightButtons = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalRightButtons)
|
||||||
}
|
}
|
||||||
|
|
||||||
open func encode(to encoder: Encoder) throws {
|
open func encode(to encoder: Encoder) throws {
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encodeIfPresent(title, forKey: .title)
|
try container.encodeIfPresent(title, forKey: .title)
|
||||||
try container.encodeModelIfPresent(titleView, forKey: .titleView)
|
|
||||||
try container.encode(hidden, forKey: .hidden)
|
try container.encode(hidden, forKey: .hidden)
|
||||||
try container.encode(backgroundColor, forKey: .backgroundColor)
|
try container.encode(backgroundColor, forKey: .backgroundColor)
|
||||||
try container.encode(transparent, forKey: .transparent)
|
try container.encode(translucent, forKey: .translucent)
|
||||||
try container.encode(tintColor, forKey: .tintColor)
|
try container.encode(tintColor, forKey: .tintColor)
|
||||||
try container.encodeIfPresent(line, forKey: .line)
|
try container.encodeIfPresent(line, forKey: .line)
|
||||||
try container.encode(systemBackButton, forKey: .systemBackButton)
|
try container.encodeIfPresent(backButton, forKey: .backButton)
|
||||||
try container.encode(showLeftPanelButton, forKey: .showLeftPanelButton)
|
try container.encode(showLeftPanelButton, forKey: .showLeftPanelButton)
|
||||||
try container.encode(showRightPanelButton, forKey: .showRightPanelButton)
|
try container.encode(showRightPanelButton, forKey: .showRightPanelButton)
|
||||||
try container.encodeIfPresent(additionalLeftItems, forKey: .additionalLeftItems)
|
try container.encodeIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons)
|
||||||
try container.encodeIfPresent(additionalRightItems, forKey: .additionalRightItems)
|
try container.encodeIfPresent(additionalRightButtons, forKey: .additionalRightButtons)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,8 +8,9 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
public class ScrollerModel: MoleculeContainerModel, MoleculeModelProtocol {
|
public class ScrollerModel: MoleculeContainerModel {
|
||||||
public static var identifier: String = "scroller"
|
public override class var identifier: String {
|
||||||
|
return "scroller"
|
||||||
|
}
|
||||||
public var moleculeName: String = ScrollerModel.identifier
|
public var moleculeName: String = ScrollerModel.identifier
|
||||||
public var backgroundColor: Color?
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,22 +20,21 @@ public class BGImageHeadlineBodyButtonModel: ContainerModel, MoleculeModelProtoc
|
|||||||
self.headlineBody = headlineBody
|
self.headlineBody = headlineBody
|
||||||
self.image = image
|
self.image = image
|
||||||
super.init()
|
super.init()
|
||||||
setDefaults()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defaults to set
|
/// Defaults to set
|
||||||
func setDefaults() {
|
public override func setDefaults() {
|
||||||
if useHorizontalMargins == nil {
|
if useHorizontalMargins == nil {
|
||||||
useHorizontalMargins = true
|
useHorizontalMargins = true
|
||||||
}
|
}
|
||||||
if useVerticalMargins == nil {
|
if useVerticalMargins == nil {
|
||||||
useVerticalMargins = true
|
useVerticalMargins = true
|
||||||
}
|
}
|
||||||
if topMarginPadding == nil {
|
if topPadding == nil {
|
||||||
topMarginPadding = PaddingDefault
|
topPadding = PaddingDefault
|
||||||
}
|
}
|
||||||
if bottomMarginPadding == nil {
|
if bottomPadding == nil {
|
||||||
bottomMarginPadding = PaddingDefault
|
bottomPadding = PaddingDefault
|
||||||
}
|
}
|
||||||
if image.height == nil {
|
if image.height == nil {
|
||||||
image.height = BGImageHeadlineBodyButton.heightConstant
|
image.height = BGImageHeadlineBodyButton.heightConstant
|
||||||
@ -59,7 +58,6 @@ public class BGImageHeadlineBodyButtonModel: ContainerModel, MoleculeModelProtoc
|
|||||||
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
||||||
button = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .button)
|
button = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .button)
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
setDefaults()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
|
|||||||
@ -33,6 +33,7 @@ import UIKit
|
|||||||
stack.stackModel?.spacing = 0
|
stack.stackModel?.spacing = 0
|
||||||
addSubview(stack)
|
addSubview(stack)
|
||||||
NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
|
NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
|
||||||
|
stack.restack()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func updateView(_ size: CGFloat) {
|
open override func updateView(_ size: CGFloat) {
|
||||||
@ -58,18 +59,11 @@ import UIKit
|
|||||||
|
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
stack.updateContainedMolecules(with: [castModel?.eyebrow,
|
||||||
eyebrow.setOptional(with: castModel?.eyebrow, delegateObject, additionalData)
|
castModel?.headline,
|
||||||
headline.setOptional(with: castModel?.headline, delegateObject, additionalData)
|
castModel?.body,
|
||||||
body.setOptional(with: castModel?.body, delegateObject, additionalData)
|
castModel?.link],
|
||||||
link.setOptional(with: castModel?.link, delegateObject, additionalData)
|
delegateObject, additionalData)
|
||||||
|
|
||||||
// Hide labels if neeeded.
|
|
||||||
stack.stackModel?.molecules[0].gone = !eyebrow.hasText
|
|
||||||
stack.stackModel?.molecules[1].gone = !headline.hasText
|
|
||||||
stack.stackModel?.molecules[2].gone = !body.hasText
|
|
||||||
stack.stackModel?.molecules[3].gone = (link.titleLabel?.text?.count ?? 0) == 0
|
|
||||||
stack.restack()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
|||||||
@ -19,22 +19,21 @@ public class HeadlineBodyCaretLinkImageModel: ContainerModel, MoleculeModelProto
|
|||||||
self.headlineBody = headlineBody
|
self.headlineBody = headlineBody
|
||||||
self.image = image
|
self.image = image
|
||||||
super.init()
|
super.init()
|
||||||
setDefaults()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defaults to set
|
/// Defaults to set
|
||||||
func setDefaults() {
|
public override func setDefaults() {
|
||||||
if useHorizontalMargins == nil {
|
if useHorizontalMargins == nil {
|
||||||
useHorizontalMargins = true
|
useHorizontalMargins = true
|
||||||
}
|
}
|
||||||
if useVerticalMargins == nil {
|
if useVerticalMargins == nil {
|
||||||
useVerticalMargins = true
|
useVerticalMargins = true
|
||||||
}
|
}
|
||||||
if topMarginPadding == nil {
|
if topPadding == nil {
|
||||||
topMarginPadding = PaddingDefault
|
topPadding = PaddingDefault
|
||||||
}
|
}
|
||||||
if bottomMarginPadding == nil {
|
if bottomPadding == nil {
|
||||||
bottomMarginPadding = PaddingDefault
|
bottomPadding = PaddingDefault
|
||||||
}
|
}
|
||||||
if image.height == nil {
|
if image.height == nil {
|
||||||
image.height = HeadLineBodyCaretLinkImage.heightConstant
|
image.height = HeadLineBodyCaretLinkImage.heightConstant
|
||||||
@ -56,7 +55,6 @@ public class HeadlineBodyCaretLinkImageModel: ContainerModel, MoleculeModelProto
|
|||||||
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
||||||
caretLink = try typeContainer.decodeIfPresent(CaretLinkModel.self, forKey: .caretLink)
|
caretLink = try typeContainer.decodeIfPresent(CaretLinkModel.self, forKey: .caretLink)
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
setDefaults()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class NumberedListModel: MoleculeStackModel {
|
@objcMembers public class NumberedListModel: StackModel {
|
||||||
public override class var identifier: String {
|
public override class var identifier: String {
|
||||||
return "numberedList"
|
return "numberedList"
|
||||||
}
|
}
|
||||||
@ -28,8 +28,7 @@ import Foundation
|
|||||||
for (index, molecule) in list.enumerated() {
|
for (index, molecule) in list.enumerated() {
|
||||||
models.append(MoleculeStackItemModel(with: StringAndMoleculeModel(string: "\(index+1).", molecule: molecule)))
|
models.append(MoleculeStackItemModel(with: StringAndMoleculeModel(string: "\(index+1).", molecule: molecule)))
|
||||||
}
|
}
|
||||||
super.init(molecules: models)
|
super.init(molecules: models, spacing: 0)
|
||||||
spacing = 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
@ -39,7 +38,7 @@ import Foundation
|
|||||||
|
|
||||||
var models: [MoleculeModelProtocol] = []
|
var models: [MoleculeModelProtocol] = []
|
||||||
for molecule in molecules {
|
for molecule in molecules {
|
||||||
models.append(molecule.molecule)
|
models.append(((molecule as! MoleculeStackItemModel).molecule as! StringAndMoleculeModel).molecule)
|
||||||
}
|
}
|
||||||
try container.encodeModels(models, forKey: .list)
|
try container.encodeModels(models, forKey: .list)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,8 +11,9 @@ import UIKit
|
|||||||
// This class is only temporarily necessary. Eventually we will have initWithModel instad of just init for moleculeviews, which will remove this need.
|
// This class is only temporarily necessary. Eventually we will have initWithModel instad of just init for moleculeviews, which will remove this need.
|
||||||
open class StringAndMoleculeStack: MoleculeStackView {
|
open class StringAndMoleculeStack: MoleculeStackView {
|
||||||
override open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
override open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
guard let model = stackModel else { return }
|
guard let model = model as? StackModelProtocol,
|
||||||
for stackItemModel in model.molecules {
|
let molcules = model.molecules as? [MoleculeStackItemModel] else { return }
|
||||||
|
for stackItemModel in molcules {
|
||||||
guard let stringAndMoleculeModel = stackItemModel.molecule as? StringAndMoleculeModel,
|
guard let stringAndMoleculeModel = stackItemModel.molecule as? StringAndMoleculeModel,
|
||||||
let molecule = MoleculeObjectMapping.shared()?.createMolecule(stringAndMoleculeModel.molecule, delegateObject: delegateObject
|
let molecule = MoleculeObjectMapping.shared()?.createMolecule(stringAndMoleculeModel.molecule, delegateObject: delegateObject
|
||||||
, additionalData: additionalData) else {
|
, additionalData: additionalData) else {
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import Foundation
|
|||||||
|
|
||||||
open class StringAndMoleculeView: View {
|
open class StringAndMoleculeView: View {
|
||||||
var label = Label.commonLabelB2(true)
|
var label = Label.commonLabelB2(true)
|
||||||
var string: String
|
|
||||||
var molecule: MoleculeViewProtocol
|
var molecule: MoleculeViewProtocol
|
||||||
|
|
||||||
var leftWidthConstraint: NSLayoutConstraint?
|
var leftWidthConstraint: NSLayoutConstraint?
|
||||||
@ -28,7 +27,7 @@ open class StringAndMoleculeView: View {
|
|||||||
|
|
||||||
// MARK: - Inits
|
// MARK: - Inits
|
||||||
public init(string: String, molecule: MoleculeViewProtocol) {
|
public init(string: String, molecule: MoleculeViewProtocol) {
|
||||||
self.string = string
|
self.label.text = string
|
||||||
self.molecule = molecule
|
self.molecule = molecule
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class UnOrderedListModel: MoleculeStackModel {
|
@objcMembers public class UnOrderedListModel: StackModel {
|
||||||
public override class var identifier: String {
|
public override class var identifier: String {
|
||||||
return "unOrderedList"
|
return "unOrderedList"
|
||||||
}
|
}
|
||||||
@ -33,8 +33,7 @@ import Foundation
|
|||||||
for molecule in list {
|
for molecule in list {
|
||||||
models.append(MoleculeStackItemModel(with: StringAndMoleculeModel(string: bulletChar, molecule: molecule)))
|
models.append(MoleculeStackItemModel(with: StringAndMoleculeModel(string: bulletChar, molecule: molecule)))
|
||||||
}
|
}
|
||||||
super.init(molecules: models)
|
super.init(molecules: models, spacing: 0)
|
||||||
spacing = 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
@ -45,7 +44,7 @@ import Foundation
|
|||||||
|
|
||||||
var models: [MoleculeModelProtocol] = []
|
var models: [MoleculeModelProtocol] = []
|
||||||
for molecule in molecules {
|
for molecule in molecules {
|
||||||
models.append(molecule.molecule)
|
models.append(((molecule as! MoleculeStackItemModel).molecule as! StringAndMoleculeModel).molecule)
|
||||||
}
|
}
|
||||||
try container.encodeModels(models, forKey: .list)
|
try container.encodeModels(models, forKey: .list)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,54 +0,0 @@
|
|||||||
//
|
|
||||||
// MoleculeStack.swift
|
|
||||||
// MVMCoreUI
|
|
||||||
//
|
|
||||||
// Created by Suresh, Kamlesh on 10/3/19.
|
|
||||||
// Copyright © 2019 Suresh, Kamlesh. All rights reserved.
|
|
||||||
//
|
|
||||||
// A stack that has a list molecule stack items.
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
@objcMembers public class MoleculeStackModel: ContainerModel, MoleculeModelProtocol, StackModelProtocol {
|
|
||||||
public class var identifier: String {
|
|
||||||
return "stack"
|
|
||||||
}
|
|
||||||
public var backgroundColor: Color?
|
|
||||||
public var molecules: [MoleculeStackItemModel]
|
|
||||||
public var axis: NSLayoutConstraint.Axis = .vertical
|
|
||||||
public var spacing: CGFloat = 16.0
|
|
||||||
public var useStackSpacingBeforeFirstItem = false
|
|
||||||
|
|
||||||
public init(molecules: [MoleculeStackItemModel]) {
|
|
||||||
self.molecules = molecules
|
|
||||||
super.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
|
||||||
case moleculeName
|
|
||||||
case molecules
|
|
||||||
case axis
|
|
||||||
case spacing
|
|
||||||
}
|
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
molecules = try typeContainer.decode([MoleculeStackItemModel].self, forKey: .molecules)
|
|
||||||
if let axisString = try typeContainer.decodeIfPresent(String.self, forKey: .axis), let optionalAxis = NSLayoutConstraint.Axis(rawValue: axisString) {
|
|
||||||
axis = optionalAxis
|
|
||||||
}
|
|
||||||
if let spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing) {
|
|
||||||
self.spacing = spacing
|
|
||||||
}
|
|
||||||
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.encodeIfPresent(molecules, forKey: .molecules)
|
|
||||||
try container.encodeIfPresent(axis.rawValueString, forKey: .axis)
|
|
||||||
try container.encodeIfPresent(spacing, forKey: .spacing)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -5,13 +5,12 @@
|
|||||||
// Created by Scott Pfeil on 2/11/19.
|
// Created by Scott Pfeil on 2/11/19.
|
||||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||||
//
|
//
|
||||||
|
// This is a dynamic stack view that creates molecules if needed on set.
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
open class MoleculeStackView: Stack<MoleculeStackModel> {
|
open class MoleculeStackView: Stack<StackModel> {
|
||||||
open override var stackModel: MoleculeStackModel? {
|
var previousModel: MoleculeModelProtocol?
|
||||||
get { return model as? MoleculeStackModel }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convenience function, adds a molecule to a MoleculeStackItem to the MoleculeStack
|
/// Convenience function, adds a molecule to a MoleculeStackItem to the MoleculeStack
|
||||||
func setup(with views: [View], lastItem: Bool) {
|
func setup(with views: [View], lastItem: Bool) {
|
||||||
@ -26,14 +25,16 @@ open class MoleculeStackView: Stack<MoleculeStackModel> {
|
|||||||
if let stackModel = stackModel {
|
if let stackModel = stackModel {
|
||||||
stackModel.molecules = models
|
stackModel.molecules = models
|
||||||
} else {
|
} else {
|
||||||
model = MoleculeStackModel(molecules: models)
|
model = StackModel(molecules: models)
|
||||||
}
|
}
|
||||||
restack()
|
restack()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Adding to stack
|
// MARK: - Adding to stack
|
||||||
/// Creates all of the stackItems for the stackItemModels
|
/// Can be subclassed to create views when we get stack item models and have no views yet
|
||||||
override open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
guard let stackItemModels = stackModel?.molecules else { return }
|
guard let stackItemModels = stackModel?.molecules else { return }
|
||||||
for model in stackItemModels {
|
for model in stackItemModels {
|
||||||
if let stackItem = MoleculeObjectMapping.shared()?.createMolecule(model, delegateObject: delegateObject, additionalData: additionalData) as? MoleculeStackItem {
|
if let stackItem = MoleculeObjectMapping.shared()?.createMolecule(model, delegateObject: delegateObject, additionalData: additionalData) as? MoleculeStackItem {
|
||||||
@ -41,4 +42,20 @@ open class MoleculeStackView: Stack<MoleculeStackModel> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open override func setStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
|
// If the items in the stack are different, clear them, create new ones.
|
||||||
|
if (previousModel == nil) || Self.nameForReuse(with: previousModel!, delegateObject) != Self.nameForReuse(with: model, delegateObject) {
|
||||||
|
removeAllItemViews()
|
||||||
|
stackItems = []
|
||||||
|
createStackItemsFromModel(model, delegateObject, additionalData)
|
||||||
|
} else {
|
||||||
|
super.setStackItemsFromModel(model, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
previousModel = self.model
|
||||||
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,6 +62,32 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A convenience function for when the stackItems are containers and we want to update them based on the contained molecules models. If model is nil, stackItem is set to gone. Restacks if necessary.
|
||||||
|
open func updateContainedMolecules(with models: [MoleculeModelProtocol?], _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
guard var stackModel = stackModel else { return }
|
||||||
|
var needsRestack = false
|
||||||
|
for (index, item) in stackItems.enumerated() {
|
||||||
|
guard let container = item as? UIView & ContainerProtocol,
|
||||||
|
let contained = container.view as? MoleculeViewProtocol else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if let model = models[index] {
|
||||||
|
contained.set(with: model, delegateObject, additionalData)
|
||||||
|
if stackModel.molecules[index].gone {
|
||||||
|
stackModel.molecules[index].gone = false
|
||||||
|
needsRestack = true
|
||||||
|
}
|
||||||
|
} else if !stackModel.molecules[index].gone {
|
||||||
|
stackModel.molecules[index].gone = true
|
||||||
|
needsRestack = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if needsRestack {
|
||||||
|
restack()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -147,18 +173,8 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
|
|||||||
}
|
}
|
||||||
|
|
||||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
let previousModel = self.model
|
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
removeAllItemViews()
|
setStackItemsFromModel(model, delegateObject, additionalData)
|
||||||
|
|
||||||
// If the items in the stack are different, clear them, create new ones.
|
|
||||||
if (previousModel == nil) || Self.nameForReuse(with: previousModel!, delegateObject) != Self.nameForReuse(with: model, delegateObject) {
|
|
||||||
stackItems = []
|
|
||||||
createStackItemsFromModel(model, delegateObject, additionalData)
|
|
||||||
} else {
|
|
||||||
setStackItemsFromModel(model, delegateObject, additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
restack()
|
restack()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,9 +232,6 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
|
|||||||
// MARK: - Subclassables
|
// MARK: - Subclassables
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
/// Can be subclassed to create views when we get stack item models and have no views yet
|
|
||||||
open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { }
|
|
||||||
|
|
||||||
/// Can be subclassed to set stack items with model when we already have views
|
/// Can be subclassed to set stack items with model when we already have views
|
||||||
open func setStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
open func setStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
guard let models = stackModel?.molecules else { return }
|
guard let models = stackModel?.molecules else { return }
|
||||||
@ -243,10 +256,10 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the stack with StackItems containing the passed in views and sets the StackModel with models.
|
/// Sets the stack with StackItems containing the passed in views and sets the StackModel with models.
|
||||||
open func set(with viewModels:[(view: UIView, model: T.AnyStackItemModel)]) {
|
open func set(with viewModels:[(view: UIView, model: StackItemModel)]) {
|
||||||
guard var stackModel = self.stackModel else { return }
|
guard var stackModel = self.stackModel else { return }
|
||||||
var stackItems: [StackItem] = []
|
var stackItems: [StackItem] = []
|
||||||
var models: [T.AnyStackItemModel] = []
|
var models: [StackItemModel] = []
|
||||||
for item in viewModels {
|
for item in viewModels {
|
||||||
stackItems.append(StackItem(andContain: item.view))
|
stackItems.append(StackItem(andContain: item.view))
|
||||||
models.append(item.model)
|
models.append(item.model)
|
||||||
@ -307,7 +320,7 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
|
|||||||
if let percent = model.percent {
|
if let percent = model.percent {
|
||||||
let multiplier = CGFloat(percent) / 100.0
|
let multiplier = CGFloat(percent) / 100.0
|
||||||
let constant = multiplier * totalSpacing
|
let constant = multiplier * totalSpacing
|
||||||
view.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: multiplier, constant: -constant).isActive = true
|
view.heightAnchor.constraint(equalTo: heightAnchor, multiplier: multiplier, constant: -constant).isActive = true
|
||||||
}
|
}
|
||||||
if lastItem {
|
if lastItem {
|
||||||
pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0)
|
pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0)
|
||||||
@ -326,7 +339,7 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
|
|||||||
if let percent = model.percent {
|
if let percent = model.percent {
|
||||||
let multiplier = CGFloat(percent) / 100.0
|
let multiplier = CGFloat(percent) / 100.0
|
||||||
let constant = multiplier * totalSpacing
|
let constant = multiplier * totalSpacing
|
||||||
view.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: multiplier, constant: -constant).isActive = true
|
view.widthAnchor.constraint(equalTo: widthAnchor, multiplier: multiplier, constant: -constant).isActive = true
|
||||||
}
|
}
|
||||||
if lastItem {
|
if lastItem {
|
||||||
pinView(contentView, toView: view, attribute: .right, relation: .equal, priority: .required, constant: 0)
|
pinView(contentView, toView: view, attribute: .right, relation: .equal, priority: .required, constant: 0)
|
||||||
|
|||||||
@ -8,17 +8,19 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class StackModel: StackModelProtocol, MoleculeModelProtocol {
|
@objcMembers public class StackModel: ContainerModel, StackModelProtocol, MoleculeModelProtocol {
|
||||||
static let defaultSpacing: CGFloat = 16.0
|
static let defaultSpacing: CGFloat = 16.0
|
||||||
|
|
||||||
public static var identifier: String = "simpleStack"
|
public class var identifier: String {
|
||||||
|
return "stack"
|
||||||
|
}
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var molecules: [StackItemModel]
|
public var molecules: [StackItemModelProtocol & MoleculeModelProtocol]
|
||||||
public var axis: NSLayoutConstraint.Axis = .vertical
|
public var axis: NSLayoutConstraint.Axis = .vertical
|
||||||
public var spacing: CGFloat = StackModel.defaultSpacing
|
public var spacing: CGFloat = StackModel.defaultSpacing
|
||||||
public var useStackSpacingBeforeFirstItem = false
|
public var useStackSpacingBeforeFirstItem = false
|
||||||
|
|
||||||
public init(molecules: [StackItemModel], axis: NSLayoutConstraint.Axis? = nil, spacing: CGFloat? = nil) {
|
public init(molecules: [StackItemModelProtocol & MoleculeModelProtocol], axis: NSLayoutConstraint.Axis? = nil, spacing: CGFloat? = nil) {
|
||||||
self.molecules = molecules
|
self.molecules = molecules
|
||||||
if let axis = axis {
|
if let axis = axis {
|
||||||
self.axis = axis
|
self.axis = axis
|
||||||
@ -26,6 +28,7 @@ import Foundation
|
|||||||
if let spacing = spacing {
|
if let spacing = spacing {
|
||||||
self.spacing = spacing
|
self.spacing = spacing
|
||||||
}
|
}
|
||||||
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
@ -38,21 +41,24 @@ import Foundation
|
|||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
molecules = try typeContainer.decodeModels(codingKey: .molecules)
|
||||||
molecules = try typeContainer.decode([StackItemModel].self, forKey: .molecules)
|
|
||||||
if let axisString = try typeContainer.decodeIfPresent(String.self, forKey: .axis), let optionalAxis = NSLayoutConstraint.Axis(rawValue: axisString) {
|
if let axisString = try typeContainer.decodeIfPresent(String.self, forKey: .axis), let optionalAxis = NSLayoutConstraint.Axis(rawValue: axisString) {
|
||||||
axis = optionalAxis
|
axis = optionalAxis
|
||||||
}
|
}
|
||||||
if let spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing) {
|
if let spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing) {
|
||||||
self.spacing = spacing
|
self.spacing = spacing
|
||||||
}
|
}
|
||||||
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encodeIfPresent(molecules, forKey: .molecules)
|
try container.encodeModels(molecules, forKey: .molecules)
|
||||||
try container.encodeIfPresent(axis.rawValueString, forKey: .axis)
|
try container.encodeIfPresent(axis.rawValueString, forKey: .axis)
|
||||||
try container.encodeIfPresent(spacing, forKey: .spacing)
|
try container.encodeIfPresent(spacing, forKey: .spacing)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,9 +9,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol StackModelProtocol {
|
public protocol StackModelProtocol {
|
||||||
associatedtype AnyStackItemModel: StackItemModelProtocol
|
var molecules: [StackItemModelProtocol & MoleculeModelProtocol] { get set }
|
||||||
|
|
||||||
var molecules: [AnyStackItemModel] { get set }
|
|
||||||
var axis: NSLayoutConstraint.Axis { get set }
|
var axis: NSLayoutConstraint.Axis { get set }
|
||||||
var spacing: CGFloat { get set }
|
var spacing: CGFloat { get set }
|
||||||
var useStackSpacingBeforeFirstItem: Bool { get set }
|
var useStackSpacingBeforeFirstItem: Bool { get set }
|
||||||
|
|||||||
@ -11,10 +11,12 @@ import Foundation
|
|||||||
|
|
||||||
public protocol ContainerModelProtocol {
|
public protocol ContainerModelProtocol {
|
||||||
var horizontalAlignment: UIStackView.Alignment? { get set }
|
var horizontalAlignment: UIStackView.Alignment? { get set }
|
||||||
var verticalAlignment: UIStackView.Alignment? { get set }
|
|
||||||
var useHorizontalMargins: Bool? { get set }
|
var useHorizontalMargins: Bool? { get set }
|
||||||
|
var leftPadding: CGFloat? { get set }
|
||||||
|
var rightPadding: CGFloat? { get set }
|
||||||
|
|
||||||
|
var verticalAlignment: UIStackView.Alignment? { get set }
|
||||||
var useVerticalMargins: Bool? { get set }
|
var useVerticalMargins: Bool? { get set }
|
||||||
var topMarginPadding: CGFloat? { get set }
|
var topPadding: CGFloat? { get set }
|
||||||
var bottomMarginPadding: CGFloat? { get set }
|
var bottomPadding: CGFloat? { get set }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,5 +12,6 @@ public protocol PageModelProtocol {
|
|||||||
var pageType: String { get set }
|
var pageType: String { get set }
|
||||||
/// Temporary: for legacy response
|
/// Temporary: for legacy response
|
||||||
var screenHeading: String? { get set }
|
var screenHeading: String? { get set }
|
||||||
|
var backgroundColor: Color? { get set }
|
||||||
var navigationItem: (NavigationItemModelProtocol & MoleculeModelProtocol)? { get set }
|
var navigationItem: (NavigationItemModelProtocol & MoleculeModelProtocol)? { get set }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// ThreeLayerTemplateModelProtocol.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 4/21/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol ThreeLayerTemplateModelProtocol: TemplateModelProtocol {
|
||||||
|
var anchorHeader: Bool { get set }
|
||||||
|
var header: MoleculeModelProtocol? { get set }
|
||||||
|
|
||||||
|
var anchorFooter: Bool { get set }
|
||||||
|
var footer: MoleculeModelProtocol? { get set }
|
||||||
|
}
|
||||||
@ -22,5 +22,8 @@ public extension TemplateProtocol where Self: ViewController {
|
|||||||
let templateModel = try decoder.decode(TemplateModel.self, from: data)
|
let templateModel = try decoder.decode(TemplateModel.self, from: data)
|
||||||
self.templateModel = templateModel
|
self.templateModel = templateModel
|
||||||
self.pageModel = templateModel as? MVMControllerModelProtocol
|
self.pageModel = templateModel as? MVMControllerModelProtocol
|
||||||
|
if let backgroundColor = templateModel.backgroundColor {
|
||||||
|
view.backgroundColor = backgroundColor.uiColor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -79,6 +79,8 @@ import Foundation
|
|||||||
|
|
||||||
|
|
||||||
open override func handleNewData() {
|
open override func handleNewData() {
|
||||||
|
topViewOutsideOfScrollArea = templateModel?.anchorHeader ?? false
|
||||||
|
bottomViewOutsideOfScrollArea = templateModel?.anchorFooter ?? false
|
||||||
setup()
|
setup()
|
||||||
registerCells()
|
registerCells()
|
||||||
super.handleNewData()
|
super.handleNewData()
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class CollectionTemplateModel: TemplateModel {
|
@objcMembers public class CollectionTemplateModel: ThreeLayerModelBase {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -16,9 +16,7 @@ import Foundation
|
|||||||
public override class var identifier: String {
|
public override class var identifier: String {
|
||||||
return "collection"
|
return "collection"
|
||||||
}
|
}
|
||||||
public var header: MoleculeModelProtocol?
|
|
||||||
public var molecules: [CollectionItemModelProtocol & MoleculeModelProtocol]?
|
public var molecules: [CollectionItemModelProtocol & MoleculeModelProtocol]?
|
||||||
public var footer: MoleculeModelProtocol?
|
|
||||||
public var columns: Int?
|
public var columns: Int?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -37,8 +35,6 @@ import Foundation
|
|||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case molecules
|
case molecules
|
||||||
case header
|
|
||||||
case footer
|
|
||||||
case columns
|
case columns
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,8 +45,6 @@ import Foundation
|
|||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
molecules = try typeContainer.decodeModelsIfPresent(codingKey: .molecules)
|
molecules = try typeContainer.decodeModelsIfPresent(codingKey: .molecules)
|
||||||
header = try typeContainer.decodeModelIfPresent(codingKey: .header)
|
|
||||||
footer = try typeContainer.decodeModelIfPresent(codingKey: .footer)
|
|
||||||
columns = try typeContainer.decodeIfPresent(Int.self, forKey: .columns)
|
columns = try typeContainer.decodeIfPresent(Int.self, forKey: .columns)
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
@ -59,8 +53,6 @@ import Foundation
|
|||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encodeModelsIfPresent(molecules, forKey: .molecules)
|
try container.encodeModelsIfPresent(molecules, forKey: .molecules)
|
||||||
try container.encodeModelIfPresent(header, forKey: .header)
|
|
||||||
try container.encodeModelIfPresent(footer, forKey: .footer)
|
|
||||||
try container.encodeIfPresent(columns, forKey: .columns)
|
try container.encodeIfPresent(columns, forKey: .columns)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class ListPageTemplateModel: TemplateModel {
|
@objcMembers public class ListPageTemplateModel: ThreeLayerModelBase {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -16,9 +16,7 @@ import Foundation
|
|||||||
public override class var identifier: String {
|
public override class var identifier: String {
|
||||||
return "list"
|
return "list"
|
||||||
}
|
}
|
||||||
public var header: MoleculeModelProtocol?
|
|
||||||
public var molecules: [ListItemModelProtocol & MoleculeModelProtocol]?
|
public var molecules: [ListItemModelProtocol & MoleculeModelProtocol]?
|
||||||
public var footer: MoleculeModelProtocol?
|
|
||||||
public var line: LineModel?
|
public var line: LineModel?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -37,8 +35,6 @@ import Foundation
|
|||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case molecules
|
case molecules
|
||||||
case header
|
|
||||||
case footer
|
|
||||||
case line
|
case line
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,8 +45,6 @@ import Foundation
|
|||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
molecules = try typeContainer.decodeModelsIfPresent(codingKey: .molecules)
|
molecules = try typeContainer.decodeModelsIfPresent(codingKey: .molecules)
|
||||||
header = try typeContainer.decodeModelIfPresent(codingKey: .header)
|
|
||||||
footer = try typeContainer.decodeModelIfPresent(codingKey: .footer)
|
|
||||||
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
@ -59,8 +53,6 @@ import Foundation
|
|||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encodeModelsIfPresent(molecules, forKey: .molecules)
|
try container.encodeModelsIfPresent(molecules, forKey: .molecules)
|
||||||
try container.encodeModelIfPresent(header, forKey: .header)
|
|
||||||
try container.encodeModelIfPresent(footer, forKey: .footer)
|
|
||||||
try container.encode(line, forKey: .line)
|
try container.encode(line, forKey: .line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,6 +81,8 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
open override func handleNewData() {
|
open override func handleNewData() {
|
||||||
|
topViewOutsideOfScrollArea = templateModel?.anchorHeader ?? false
|
||||||
|
bottomViewOutsideOfScrollArea = templateModel?.anchorFooter ?? false
|
||||||
setup()
|
setup()
|
||||||
registerWithTable()
|
registerWithTable()
|
||||||
super.handleNewData()
|
super.handleNewData()
|
||||||
|
|||||||
@ -11,6 +11,12 @@ import UIKit
|
|||||||
open class MoleculeStackTemplate: ThreeLayerViewController, TemplateProtocol {
|
open class MoleculeStackTemplate: ThreeLayerViewController, TemplateProtocol {
|
||||||
var observer: NSKeyValueObservation?
|
var observer: NSKeyValueObservation?
|
||||||
public var templateModel: StackPageTemplateModel?
|
public var templateModel: StackPageTemplateModel?
|
||||||
|
|
||||||
|
open override func handleNewData() {
|
||||||
|
topViewOutsideOfScroll = templateModel?.anchorHeader ?? false
|
||||||
|
bottomViewOutsideOfScroll = templateModel?.anchorFooter ?? false
|
||||||
|
super.handleNewData()
|
||||||
|
}
|
||||||
|
|
||||||
open override func parsePageJSON() throws {
|
open override func parsePageJSON() throws {
|
||||||
try parseTemplate(json: loadObject?.pageJSON)
|
try parseTemplate(json: loadObject?.pageJSON)
|
||||||
|
|||||||
@ -9,31 +9,24 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class StackPageTemplateModel: TemplateModel {
|
@objcMembers public class StackPageTemplateModel: ThreeLayerModelBase {
|
||||||
public override class var identifier: String {
|
public override class var identifier: String {
|
||||||
return "stack"
|
return "stack"
|
||||||
}
|
}
|
||||||
|
public var moleculeStack: StackModel
|
||||||
public var header: MoleculeModelProtocol?
|
|
||||||
public var moleculeStack: MoleculeStackModel
|
|
||||||
public var footer: MoleculeModelProtocol?
|
|
||||||
|
|
||||||
public init(pageType: String, moleculeStack: MoleculeStackModel) {
|
public init(pageType: String, moleculeStack: StackModel) {
|
||||||
self.moleculeStack = moleculeStack
|
self.moleculeStack = moleculeStack
|
||||||
super.init(pageType: pageType)
|
super.init(pageType: pageType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case header
|
|
||||||
case footer
|
|
||||||
case stack
|
case stack
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
moleculeStack = try typeContainer.decode(MoleculeStackModel.self, forKey: .stack)
|
moleculeStack = try typeContainer.decode(StackModel.self, forKey: .stack)
|
||||||
header = try typeContainer.decodeModelIfPresent(codingKey: .header)
|
|
||||||
footer = try typeContainer.decodeModelIfPresent(codingKey: .footer)
|
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +34,5 @@ import Foundation
|
|||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeStack, forKey: .stack)
|
try container.encode(moleculeStack, forKey: .stack)
|
||||||
try container.encodeModelIfPresent(header, forKey: .header)
|
|
||||||
try container.encodeModelIfPresent(footer, forKey: .footer)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import Foundation
|
|||||||
// Although this is done in the extension, it is needed for the encoding.
|
// Although this is done in the extension, it is needed for the encoding.
|
||||||
return Self.identifier
|
return Self.identifier
|
||||||
}
|
}
|
||||||
|
public var backgroundColor: Color?
|
||||||
public var screenHeading: String?
|
public var screenHeading: String?
|
||||||
public var navigationItem: (NavigationItemModelProtocol & MoleculeModelProtocol)?
|
public var navigationItem: (NavigationItemModelProtocol & MoleculeModelProtocol)?
|
||||||
public var formRules: [FormGroupRule]?
|
public var formRules: [FormGroupRule]?
|
||||||
@ -29,6 +30,7 @@ import Foundation
|
|||||||
case pageType
|
case pageType
|
||||||
case template
|
case template
|
||||||
case screenHeading
|
case screenHeading
|
||||||
|
case backgroundColor
|
||||||
case formRules
|
case formRules
|
||||||
case navigationItem
|
case navigationItem
|
||||||
}
|
}
|
||||||
@ -37,6 +39,7 @@ import Foundation
|
|||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
pageType = try typeContainer.decode(String.self, forKey: .pageType)
|
pageType = try typeContainer.decode(String.self, forKey: .pageType)
|
||||||
screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading)
|
screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading)
|
||||||
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
formRules = try typeContainer.decodeIfPresent([FormGroupRule].self, forKey: .formRules)
|
formRules = try typeContainer.decodeIfPresent([FormGroupRule].self, forKey: .formRules)
|
||||||
navigationItem = try typeContainer.decodeModelIfPresent(codingKey: .navigationItem)
|
navigationItem = try typeContainer.decodeModelIfPresent(codingKey: .navigationItem)
|
||||||
}
|
}
|
||||||
@ -45,6 +48,7 @@ import Foundation
|
|||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(pageType, forKey: .pageType)
|
try container.encode(pageType, forKey: .pageType)
|
||||||
try container.encode(template, forKey: .template)
|
try container.encode(template, forKey: .template)
|
||||||
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
try container.encodeIfPresent(screenHeading, forKey: .screenHeading)
|
try container.encodeIfPresent(screenHeading, forKey: .screenHeading)
|
||||||
try container.encodeIfPresent(formRules, forKey: .formRules)
|
try container.encodeIfPresent(formRules, forKey: .formRules)
|
||||||
try container.encodeModelIfPresent(navigationItem, forKey: .navigationItem)
|
try container.encodeModelIfPresent(navigationItem, forKey: .navigationItem)
|
||||||
|
|||||||
15
MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplate.swift
Normal file
15
MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplate.swift
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// ThreeLayerCenterTemplate.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 4/21/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers open class ThreeLayerCenterTemplate: ThreeLayerTemplate<ThreeLayerCenterPageTemplateModel> {
|
||||||
|
open override func spaceBetweenTopAndMiddle() -> CGFloat? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// ThreeLayerCenterTemplateModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 4/21/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers public class ThreeLayerCenterPageTemplateModel: ThreeLayerPageTemplateModel {
|
||||||
|
public override class var identifier: String {
|
||||||
|
return "threeLayerCenter"
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user