merge
This commit is contained in:
commit
93b43d6333
@ -202,6 +202,9 @@
|
|||||||
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 */; };
|
||||||
BB6C6AC924225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6AC72422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift */; };
|
BB6C6AC924225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6AC72422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift */; };
|
||||||
|
BBAA4F03243D8E3B005AAD5F /* RadioBoxes.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBAA4EFF243D8E3B005AAD5F /* RadioBoxes.swift */; };
|
||||||
|
BBAA4F04243D8E3B005AAD5F /* RadioBoxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBAA4F00243D8E3B005AAD5F /* RadioBoxModel.swift */; };
|
||||||
|
BBAA4F05243D8E3B005AAD5F /* RadioBoxesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBAA4F01243D8E3B005AAD5F /* RadioBoxesModel.swift */; };
|
||||||
BBBBC87C24374A4900B0F079 /* ListThreeColumnBillChangesDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBBC87A24374A4900B0F079 /* ListThreeColumnBillChangesDivider.swift */; };
|
BBBBC87C24374A4900B0F079 /* ListThreeColumnBillChangesDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBBC87A24374A4900B0F079 /* ListThreeColumnBillChangesDivider.swift */; };
|
||||||
BBBBC87D24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBBC87B24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift */; };
|
BBBBC87D24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBBC87B24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift */; };
|
||||||
C003506123AA94CD00B6AC29 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = C003506023AA94CD00B6AC29 /* Button.swift */; };
|
C003506123AA94CD00B6AC29 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = C003506023AA94CD00B6AC29 /* Button.swift */; };
|
||||||
@ -264,6 +267,9 @@
|
|||||||
D264FAA1243CF66B00D98315 /* ContainerCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAA0243CF66B00D98315 /* ContainerCollectionReusableView.swift */; };
|
D264FAA1243CF66B00D98315 /* ContainerCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAA0243CF66B00D98315 /* ContainerCollectionReusableView.swift */; };
|
||||||
D264FAA3243E632F00D98315 /* ProgrammaticCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAA2243E632F00D98315 /* ProgrammaticCollectionViewController.swift */; };
|
D264FAA3243E632F00D98315 /* ProgrammaticCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAA2243E632F00D98315 /* ProgrammaticCollectionViewController.swift */; };
|
||||||
D264FAA5243F66A500D98315 /* CollectionTemplateItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAA4243F66A500D98315 /* CollectionTemplateItemProtocol.swift */; };
|
D264FAA5243F66A500D98315 /* CollectionTemplateItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAA4243F66A500D98315 /* CollectionTemplateItemProtocol.swift */; };
|
||||||
|
D264FAA7243FE13B00D98315 /* RadioBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAA6243FE13B00D98315 /* RadioBox.swift */; };
|
||||||
|
D264FAAA2440F97600D98315 /* CollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAA92440F97600D98315 /* CollectionView.swift */; };
|
||||||
|
D264FAAC2441009400D98315 /* RadioBoxCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAAB2441009400D98315 /* RadioBoxCollectionViewCell.swift */; };
|
||||||
D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368A23609801006832FA /* MoleculeStackItemModel.swift */; };
|
D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368A23609801006832FA /* MoleculeStackItemModel.swift */; };
|
||||||
D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */; };
|
D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */; };
|
||||||
D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */; };
|
D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */; };
|
||||||
@ -622,6 +628,9 @@
|
|||||||
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>"; };
|
||||||
BB6C6AC72422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerShortModel.swift; sourceTree = "<group>"; };
|
BB6C6AC72422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerShortModel.swift; sourceTree = "<group>"; };
|
||||||
|
BBAA4EFF243D8E3B005AAD5F /* RadioBoxes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxes.swift; sourceTree = "<group>"; };
|
||||||
|
BBAA4F00243D8E3B005AAD5F /* RadioBoxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxModel.swift; sourceTree = "<group>"; };
|
||||||
|
BBAA4F01243D8E3B005AAD5F /* RadioBoxesModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxesModel.swift; sourceTree = "<group>"; };
|
||||||
BBBBC87A24374A4900B0F079 /* ListThreeColumnBillChangesDivider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnBillChangesDivider.swift; sourceTree = "<group>"; };
|
BBBBC87A24374A4900B0F079 /* ListThreeColumnBillChangesDivider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnBillChangesDivider.swift; sourceTree = "<group>"; };
|
||||||
BBBBC87B24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnBillChangesDividerModel.swift; sourceTree = "<group>"; };
|
BBBBC87B24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnBillChangesDividerModel.swift; sourceTree = "<group>"; };
|
||||||
C003506023AA94CD00B6AC29 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = "<group>"; };
|
C003506023AA94CD00B6AC29 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = "<group>"; };
|
||||||
@ -684,6 +693,9 @@
|
|||||||
D264FAA0243CF66B00D98315 /* ContainerCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerCollectionReusableView.swift; sourceTree = "<group>"; };
|
D264FAA0243CF66B00D98315 /* ContainerCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerCollectionReusableView.swift; sourceTree = "<group>"; };
|
||||||
D264FAA2243E632F00D98315 /* ProgrammaticCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgrammaticCollectionViewController.swift; sourceTree = "<group>"; };
|
D264FAA2243E632F00D98315 /* ProgrammaticCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgrammaticCollectionViewController.swift; sourceTree = "<group>"; };
|
||||||
D264FAA4243F66A500D98315 /* CollectionTemplateItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionTemplateItemProtocol.swift; sourceTree = "<group>"; };
|
D264FAA4243F66A500D98315 /* CollectionTemplateItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionTemplateItemProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
D264FAA6243FE13B00D98315 /* RadioBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBox.swift; sourceTree = "<group>"; };
|
||||||
|
D264FAA92440F97600D98315 /* CollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionView.swift; sourceTree = "<group>"; };
|
||||||
|
D264FAAB2441009400D98315 /* RadioBoxCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||||
D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropDownFilterTableViewCell.swift; sourceTree = "<group>"; };
|
D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropDownFilterTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemModel.swift; sourceTree = "<group>"; };
|
D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemModel.swift; sourceTree = "<group>"; };
|
||||||
D274CA322236A78900B01B62 /* FooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FooterView.swift; sourceTree = "<group>"; };
|
D274CA322236A78900B01B62 /* FooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FooterView.swift; sourceTree = "<group>"; };
|
||||||
@ -1404,6 +1416,23 @@
|
|||||||
path = Doughnut;
|
path = Doughnut;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
D264FAA8243FE17A00D98315 /* Selectors */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D264FAAB2441009400D98315 /* RadioBoxCollectionViewCell.swift */,
|
||||||
|
BBAA4F01243D8E3B005AAD5F /* RadioBoxesModel.swift */,
|
||||||
|
BBAA4EFF243D8E3B005AAD5F /* RadioBoxes.swift */,
|
||||||
|
BBAA4F00243D8E3B005AAD5F /* RadioBoxModel.swift */,
|
||||||
|
D264FAA6243FE13B00D98315 /* RadioBox.swift */,
|
||||||
|
0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */,
|
||||||
|
011D95AE2407266E000E3791 /* RadioButtonModel.swift */,
|
||||||
|
01004F2F22721C3800991ECC /* RadioButton.swift */,
|
||||||
|
31BE15CA23D8924C00452370 /* CheckboxModel.swift */,
|
||||||
|
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */,
|
||||||
|
);
|
||||||
|
path = Selectors;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
D29DF0C221E404D4003B2FB9 = {
|
D29DF0C221E404D4003B2FB9 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -1479,6 +1508,7 @@
|
|||||||
D29DF10D21E67A70003B2FB9 /* Atoms */ = {
|
D29DF10D21E67A70003B2FB9 /* Atoms */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
D264FAA8243FE17A00D98315 /* Selectors */,
|
||||||
D29DF22B21E6A0FA003B2FB9 /* TextFields */,
|
D29DF22B21E6A0FA003B2FB9 /* TextFields */,
|
||||||
D29DF17D21E69E26003B2FB9 /* Views */,
|
D29DF17D21E69E26003B2FB9 /* Views */,
|
||||||
D29DF16821E69E1F003B2FB9 /* Buttons */,
|
D29DF16821E69E1F003B2FB9 /* Buttons */,
|
||||||
@ -1621,9 +1651,6 @@
|
|||||||
DBC4391A224421A0001AB423 /* CaretLink.swift */,
|
DBC4391A224421A0001AB423 /* CaretLink.swift */,
|
||||||
D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */,
|
D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */,
|
||||||
D2E2A99E23E07F8A000B42E6 /* PillButton.swift */,
|
D2E2A99E23E07F8A000B42E6 /* PillButton.swift */,
|
||||||
0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */,
|
|
||||||
011D95AE2407266E000E3791 /* RadioButtonModel.swift */,
|
|
||||||
01004F2F22721C3800991ECC /* RadioButton.swift */,
|
|
||||||
);
|
);
|
||||||
path = Buttons;
|
path = Buttons;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1647,8 +1674,6 @@
|
|||||||
017BEB7A236763000024EF95 /* LineModel.swift */,
|
017BEB7A236763000024EF95 /* LineModel.swift */,
|
||||||
D213347623843825008E41B3 /* Line.swift */,
|
D213347623843825008E41B3 /* Line.swift */,
|
||||||
94C2D9822386F3E30006CF46 /* Label */,
|
94C2D9822386F3E30006CF46 /* Label */,
|
||||||
31BE15CA23D8924C00452370 /* CheckboxModel.swift */,
|
|
||||||
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */,
|
|
||||||
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */,
|
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */,
|
||||||
0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */,
|
0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */,
|
||||||
D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */,
|
D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */,
|
||||||
@ -1823,6 +1848,7 @@
|
|||||||
0AE14F63238315D2005417F8 /* TextField.swift */,
|
0AE14F63238315D2005417F8 /* TextField.swift */,
|
||||||
D2755D7A23689C7500485468 /* TableViewCell.swift */,
|
D2755D7A23689C7500485468 /* TableViewCell.swift */,
|
||||||
D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */,
|
D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */,
|
||||||
|
D264FAA92440F97600D98315 /* CollectionView.swift */,
|
||||||
0A5D59C323AD488600EFD9E9 /* Protocols */,
|
0A5D59C323AD488600EFD9E9 /* Protocols */,
|
||||||
);
|
);
|
||||||
path = BaseClasses;
|
path = BaseClasses;
|
||||||
@ -2032,6 +2058,7 @@
|
|||||||
AA56A20F243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift in Sources */,
|
AA56A20F243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.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 */,
|
||||||
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */,
|
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */,
|
||||||
D2FB151D23A40F1500C20E10 /* MoleculeStackItem.swift in Sources */,
|
D2FB151D23A40F1500C20E10 /* MoleculeStackItem.swift in Sources */,
|
||||||
AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */,
|
AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */,
|
||||||
@ -2091,6 +2118,7 @@
|
|||||||
D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */,
|
D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */,
|
||||||
014AA72F23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift in Sources */,
|
014AA72F23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift in Sources */,
|
||||||
0A21DB91235E0EDB00C160A2 /* DigitBox.swift in Sources */,
|
0A21DB91235E0EDB00C160A2 /* DigitBox.swift in Sources */,
|
||||||
|
BBAA4F04243D8E3B005AAD5F /* RadioBoxModel.swift in Sources */,
|
||||||
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 */,
|
||||||
@ -2144,6 +2172,7 @@
|
|||||||
011D959B240451E3000E3791 /* RuleRequiredModel.swift in Sources */,
|
011D959B240451E3000E3791 /* RuleRequiredModel.swift in Sources */,
|
||||||
526A265C240D1FF700B0D828 /* ListTwoColumnCompareChangesModel.swift in Sources */,
|
526A265C240D1FF700B0D828 /* ListTwoColumnCompareChangesModel.swift in Sources */,
|
||||||
D2A92886241ACD99004E01C6 /* ProgrammaticTableViewController.swift in Sources */,
|
D2A92886241ACD99004E01C6 /* ProgrammaticTableViewController.swift in Sources */,
|
||||||
|
BBAA4F05243D8E3B005AAD5F /* RadioBoxesModel.swift in Sources */,
|
||||||
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 */,
|
||||||
@ -2217,6 +2246,7 @@
|
|||||||
526A265E240D200500B0D828 /* ListTwoColumnCompareChanges.swift in Sources */,
|
526A265E240D200500B0D828 /* ListTwoColumnCompareChanges.swift in Sources */,
|
||||||
8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */,
|
8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */,
|
||||||
D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */,
|
D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */,
|
||||||
|
D264FAAC2441009400D98315 /* RadioBoxCollectionViewCell.swift in Sources */,
|
||||||
BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */,
|
BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */,
|
||||||
D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */,
|
D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */,
|
||||||
012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */,
|
012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */,
|
||||||
@ -2240,6 +2270,7 @@
|
|||||||
8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */,
|
8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */,
|
||||||
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */,
|
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */,
|
||||||
8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */,
|
8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */,
|
||||||
|
BBAA4F03243D8E3B005AAD5F /* RadioBoxes.swift in Sources */,
|
||||||
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
|
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
|
||||||
525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */,
|
525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */,
|
||||||
0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */,
|
0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */,
|
||||||
@ -2359,6 +2390,7 @@
|
|||||||
D260106523D0CEA700764D80 /* StackModel.swift in Sources */,
|
D260106523D0CEA700764D80 /* StackModel.swift in Sources */,
|
||||||
0A6682AA2435125F00AD3CA1 /* Styler.swift in Sources */,
|
0A6682AA2435125F00AD3CA1 /* Styler.swift in Sources */,
|
||||||
D29770F521F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m in Sources */,
|
D29770F521F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m in Sources */,
|
||||||
|
D264FAA7243FE13B00D98315 /* RadioBox.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
183
MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift
Normal file
183
MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
//
|
||||||
|
// RadioBox.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 4/9/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class RadioBox: Control {
|
||||||
|
public let label = Label.createLabelRegularBodySmall(true)
|
||||||
|
public let subTextLabel = Label.createLabelRegularMicro(true)
|
||||||
|
public var isOutOfStock = false
|
||||||
|
public var accentColor = UIColor.mvmRed
|
||||||
|
|
||||||
|
public let innerPadding: CGFloat = 12.0
|
||||||
|
|
||||||
|
private var borderLayer: CALayer?
|
||||||
|
private var strikeLayer: CALayer?
|
||||||
|
private var maskLayer: CALayer?
|
||||||
|
|
||||||
|
public var subTextLabelHeightConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
|
public var radioBoxModel: RadioBoxModel? {
|
||||||
|
return model as? RadioBoxModel
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - MVMCoreViewProtocol
|
||||||
|
|
||||||
|
open override func updateView(_ size: CGFloat) {
|
||||||
|
super.updateView(size)
|
||||||
|
label.updateView(size)
|
||||||
|
subTextLabel.updateView(size)
|
||||||
|
layer.setNeedsDisplay()
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
|
||||||
|
layer.delegate = self
|
||||||
|
layer.borderColor = UIColor.black.cgColor
|
||||||
|
layer.borderWidth = 1
|
||||||
|
|
||||||
|
label.numberOfLines = 1
|
||||||
|
addSubview(label)
|
||||||
|
NSLayoutConstraint.constraintPinSubview(label, pinTop: true, topConstant: innerPadding, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: innerPadding, pinRight: true, rightConstant: innerPadding)
|
||||||
|
|
||||||
|
subTextLabel.textColor = .mvmCoolGray6
|
||||||
|
subTextLabel.numberOfLines = 1
|
||||||
|
addSubview(subTextLabel)
|
||||||
|
NSLayoutConstraint.constraintPinSubview(subTextLabel, pinTop: false, topConstant:0, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: innerPadding, pinRight: true, rightConstant: innerPadding)
|
||||||
|
bottomAnchor.constraint(greaterThanOrEqualTo: subTextLabel.bottomAnchor, constant: innerPadding).isActive = true
|
||||||
|
subTextLabel.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 2).isActive = true
|
||||||
|
subTextLabelHeightConstraint = subTextLabel.heightAnchor.constraint(equalToConstant: 0)
|
||||||
|
subTextLabelHeightConstraint?.isActive = true
|
||||||
|
|
||||||
|
addTarget(self, action: #selector(selectBox), for: .touchUpInside)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - MoleculeViewProtocol
|
||||||
|
|
||||||
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
guard let model = model as? RadioBoxModel else { return }
|
||||||
|
isSelected = model.selected
|
||||||
|
isEnabled = model.enabled
|
||||||
|
label.text = model.text
|
||||||
|
subTextLabel.text = model.subText
|
||||||
|
isOutOfStock = model.strikethrough
|
||||||
|
subTextLabelHeightConstraint?.isActive = (subTextLabel.text?.count ?? 0) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - State Handling
|
||||||
|
|
||||||
|
open override func draw(_ layer: CALayer, in ctx: CGContext) {
|
||||||
|
// Draw the strikethrough
|
||||||
|
strikeLayer?.removeFromSuperlayer()
|
||||||
|
if isOutOfStock {
|
||||||
|
let line = getStrikeThrough(color: .black, thickness: 1)
|
||||||
|
layer.addSublayer(line)
|
||||||
|
strikeLayer = line
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the border
|
||||||
|
borderLayer?.removeFromSuperlayer()
|
||||||
|
if isSelected {
|
||||||
|
layer.borderWidth = 0
|
||||||
|
let border = getSelectedBorder()
|
||||||
|
layer.addSublayer(border)
|
||||||
|
borderLayer = border
|
||||||
|
} else {
|
||||||
|
layer.borderWidth = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle Mask
|
||||||
|
maskLayer?.removeFromSuperlayer()
|
||||||
|
if !isEnabled {
|
||||||
|
let mask = getMaskLayer()
|
||||||
|
layer.mask = mask
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
// Accounts for any size changes
|
||||||
|
layer.setNeedsDisplay()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc open func selectBox() {
|
||||||
|
isSelected = true
|
||||||
|
radioBoxModel?.selected = isSelected
|
||||||
|
layer.setNeedsDisplay()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc open func deselectBox() {
|
||||||
|
isSelected = false
|
||||||
|
radioBoxModel?.selected = isSelected
|
||||||
|
layer.setNeedsDisplay()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the selected state border
|
||||||
|
func getSelectedBorder() -> CAShapeLayer {
|
||||||
|
let layer = CAShapeLayer()
|
||||||
|
|
||||||
|
let topLineWidth: CGFloat = 4
|
||||||
|
let topLinePath = UIBezierPath()
|
||||||
|
topLinePath.lineWidth = topLineWidth
|
||||||
|
topLinePath.move(to: CGPoint(x: 0, y: topLineWidth / 2.0))
|
||||||
|
topLinePath.addLine(to: CGPoint(x: bounds.width, y: topLineWidth / 2.0))
|
||||||
|
|
||||||
|
let topLineLayer = CAShapeLayer()
|
||||||
|
topLineLayer.fillColor = nil
|
||||||
|
topLineLayer.strokeColor = UIColor.mvmRed.cgColor
|
||||||
|
topLineLayer.lineWidth = 4
|
||||||
|
topLineLayer.path = topLinePath.cgPath
|
||||||
|
layer.addSublayer(topLineLayer)
|
||||||
|
|
||||||
|
let lineWidth: CGFloat = 1
|
||||||
|
let halfLineWidth: CGFloat = 0.5
|
||||||
|
let linePath = UIBezierPath()
|
||||||
|
linePath.move(to: CGPoint(x: halfLineWidth, y: topLineWidth))
|
||||||
|
linePath.addLine(to: CGPoint(x: halfLineWidth, y: bounds.height))
|
||||||
|
linePath.move(to: CGPoint(x: 0, y: bounds.height - halfLineWidth))
|
||||||
|
linePath.addLine(to: CGPoint(x: bounds.width, y: bounds.height - halfLineWidth))
|
||||||
|
linePath.move(to: CGPoint(x: bounds.width - halfLineWidth, y: bounds.height))
|
||||||
|
linePath.addLine(to: CGPoint(x: bounds.width - halfLineWidth, y: topLineWidth))
|
||||||
|
|
||||||
|
let borderLayer = CAShapeLayer()
|
||||||
|
borderLayer.fillColor = nil
|
||||||
|
borderLayer.strokeColor = UIColor.black.cgColor
|
||||||
|
borderLayer.lineWidth = lineWidth
|
||||||
|
borderLayer.path = linePath.cgPath
|
||||||
|
layer.addSublayer(borderLayer)
|
||||||
|
|
||||||
|
return layer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds a border to edge
|
||||||
|
func getStrikeThrough(color: UIColor, thickness: CGFloat) -> CAShapeLayer {
|
||||||
|
let border = CAShapeLayer()
|
||||||
|
border.name = "strikethrough"
|
||||||
|
border.fillColor = nil
|
||||||
|
border.opacity = 1.0
|
||||||
|
border.lineWidth = thickness
|
||||||
|
border.strokeColor = color.cgColor
|
||||||
|
|
||||||
|
let linePath = UIBezierPath()
|
||||||
|
linePath.move(to: CGPoint(x: 0, y: bounds.height))
|
||||||
|
linePath.addLine(to: CGPoint(x: bounds.width, y: 0))
|
||||||
|
border.path = linePath.cgPath
|
||||||
|
return border
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMaskLayer() -> CALayer {
|
||||||
|
let mask = CALayer()
|
||||||
|
mask.backgroundColor = UIColor.white.cgColor
|
||||||
|
mask.opacity = 0.3
|
||||||
|
mask.frame = bounds
|
||||||
|
return mask
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// RadioBoxCollectionViewCell.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Dhamodaram Nandi on 01/04/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
open class RadioBoxCollectionViewCell: CollectionViewCell {
|
||||||
|
let radioBox = RadioBox()
|
||||||
|
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
addMolecule(radioBox)
|
||||||
|
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? RadioBoxModel else { return }
|
||||||
|
radioBox.set(with: model, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
}
|
||||||
68
MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift
Normal file
68
MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
//
|
||||||
|
// RadioBoxModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Dhamodaram Nandi on 31/03/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
@objcMembers public class RadioBoxModel: MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "radioBox"
|
||||||
|
public var text: String
|
||||||
|
public var subText: String?
|
||||||
|
public var backgroundColor: Color? = Color(uiColor: .white)
|
||||||
|
public var selectedAccentColor = Color(uiColor: .mvmRed)
|
||||||
|
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 text
|
||||||
|
case subText
|
||||||
|
case selectedAccentColor
|
||||||
|
case backgroundColor
|
||||||
|
case selected
|
||||||
|
case enabled
|
||||||
|
case strikethrough
|
||||||
|
case fieldValue
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
text = try typeContainer.decode(String.self, forKey: .text)
|
||||||
|
subText = try typeContainer.decodeIfPresent(String.self, forKey: .subText)
|
||||||
|
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor) {
|
||||||
|
selectedAccentColor = color
|
||||||
|
}
|
||||||
|
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) {
|
||||||
|
backgroundColor = color
|
||||||
|
}
|
||||||
|
if let isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) {
|
||||||
|
selected = isSelected
|
||||||
|
}
|
||||||
|
if let isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
||||||
|
enabled = isEnabled
|
||||||
|
}
|
||||||
|
if let isStrikeTrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) {
|
||||||
|
strikethrough = isStrikeTrough
|
||||||
|
}
|
||||||
|
|
||||||
|
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.encode(text, forKey: .text)
|
||||||
|
try container.encodeIfPresent(subText, forKey: .subText)
|
||||||
|
try container.encode(selectedAccentColor, forKey: .selectedAccentColor)
|
||||||
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
|
try container.encode(selected, forKey: .selected)
|
||||||
|
try container.encode(enabled, forKey: .enabled)
|
||||||
|
try container.encode(strikethrough, forKey: .strikethrough)
|
||||||
|
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
143
MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift
Normal file
143
MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
//
|
||||||
|
// RadioBoxes.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Dhamodaram Nandi on 31/03/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class RadioBoxes: View {
|
||||||
|
|
||||||
|
public var collectionView: CollectionView!
|
||||||
|
public var collectionViewHeight: NSLayoutConstraint!
|
||||||
|
private let boxWidth: CGFloat = 151.0
|
||||||
|
private let boxHeight: CGFloat = 64.0
|
||||||
|
private let itemSpacing: CGFloat = 8.0
|
||||||
|
|
||||||
|
private var delegateObject: MVMCoreUIDelegateObject?
|
||||||
|
|
||||||
|
/// The models for the molecules.
|
||||||
|
public var boxes: [RadioBoxModel]?
|
||||||
|
|
||||||
|
private var size: CGFloat?
|
||||||
|
|
||||||
|
open override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
// Accounts for any collection size changes
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.collectionView.collectionViewLayout.invalidateLayout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - MVMCoreViewProtocol
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
collectionView = createCollectionView()
|
||||||
|
addSubview(collectionView)
|
||||||
|
NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView)
|
||||||
|
collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 300)
|
||||||
|
collectionViewHeight?.isActive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - MoleculeViewProtocol
|
||||||
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
self.delegateObject = delegateObject
|
||||||
|
|
||||||
|
guard let radioBoxesModel = model as? RadioBoxesModel else { return }
|
||||||
|
boxes = radioBoxesModel.boxes
|
||||||
|
FormValidator.setupValidation(for: radioBoxesModel, delegate: delegateObject?.formHolderDelegate)
|
||||||
|
|
||||||
|
backgroundColor = radioBoxesModel.backgroundColor?.uiColor
|
||||||
|
registerCells()
|
||||||
|
setHeight()
|
||||||
|
collectionView.reloadData()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc override open func updateView(_ size: CGFloat) {
|
||||||
|
super.updateView(size)
|
||||||
|
self.size = size
|
||||||
|
collectionView.updateView(size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Creation
|
||||||
|
|
||||||
|
/// Creates the layout for the collection.
|
||||||
|
open func createCollectionViewLayout() -> UICollectionViewLayout {
|
||||||
|
let layout = UICollectionViewFlowLayout()
|
||||||
|
layout.scrollDirection = .vertical
|
||||||
|
layout.minimumLineSpacing = itemSpacing
|
||||||
|
layout.minimumInteritemSpacing = itemSpacing
|
||||||
|
return layout
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates the collection view.
|
||||||
|
open func createCollectionView() -> CollectionView {
|
||||||
|
let collection = CollectionView(frame: .zero, collectionViewLayout: createCollectionViewLayout())
|
||||||
|
collection.dataSource = self
|
||||||
|
collection.delegate = self
|
||||||
|
return collection
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Registers the cells with the collection view
|
||||||
|
open func registerCells() {
|
||||||
|
collectionView.register(RadioBoxCollectionViewCell.self, forCellWithReuseIdentifier: "RadioBoxCollectionViewCell")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - JSON Setters
|
||||||
|
open func setHeight() {
|
||||||
|
guard let boxes = boxes, boxes.count > 0 else {
|
||||||
|
collectionViewHeight.constant = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the height
|
||||||
|
let rows = ceil(CGFloat(boxes.count) / 2.0)
|
||||||
|
let height = (rows * boxHeight) + ((rows - 1) * itemSpacing)
|
||||||
|
collectionViewHeight?.constant = height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension RadioBoxes: UICollectionViewDelegateFlowLayout {
|
||||||
|
open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
|
||||||
|
let itemWidth: CGFloat = (collectionView.bounds.width - itemSpacing) / 2
|
||||||
|
return CGSize(width: itemWidth, height: boxHeight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension RadioBoxes: UICollectionViewDataSource {
|
||||||
|
open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
|
return boxes?.count ?? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
|
guard let molecule = boxes?[indexPath.row],
|
||||||
|
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioBoxCollectionViewCell", for: indexPath) as? RadioBoxCollectionViewCell else {
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
cell.radioBox.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 RadioBoxes: UICollectionViewDelegate {
|
||||||
|
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
|
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return }
|
||||||
|
cell.radioBox.selectBox()
|
||||||
|
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
|
||||||
|
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return }
|
||||||
|
cell.radioBox.deselectBox()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
57
MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift
Normal file
57
MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// RadioBoxesModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Dhamodaram Nandi on 31/03/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
@objcMembers public class RadioBoxesModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||||
|
public static var identifier: String = "radioBoxes"
|
||||||
|
public var backgroundColor: Color?
|
||||||
|
public var selectedAccentColor: Color?
|
||||||
|
public var boxes: [RadioBoxModel]
|
||||||
|
public var fieldKey: String?
|
||||||
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
|
public var baseValue: AnyHashable?
|
||||||
|
|
||||||
|
/// Returns the fieldValue of the selected box, otherwise the text of the selected box.
|
||||||
|
public func formFieldValue() -> AnyHashable? {
|
||||||
|
let selectedBox = boxes.first { (box) -> Bool in
|
||||||
|
return box.selected
|
||||||
|
}
|
||||||
|
return selectedBox?.fieldValue ?? selectedBox?.text
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case selectedAccentColor
|
||||||
|
case backgroundColor
|
||||||
|
case boxes
|
||||||
|
case fieldKey
|
||||||
|
case groupName
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
selectedAccentColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor)
|
||||||
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
|
boxes = try typeContainer.decode([RadioBoxModel].self, forKey: .boxes)
|
||||||
|
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.encode(boxes, forKey: .boxes)
|
||||||
|
try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor)
|
||||||
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
|
try container.encode(groupName, forKey: .groupName)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -20,6 +20,12 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override var isSelected: Bool {
|
||||||
|
didSet {
|
||||||
|
radioModel?.state = isSelected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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?
|
||||||
@ -55,7 +55,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public func formFieldValue() -> AnyHashable? {
|
public func formFieldValue() -> AnyHashable? {
|
||||||
return state
|
return fieldValue
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -17,15 +17,30 @@ import Foundation
|
|||||||
public var fieldKey: String?
|
public var fieldKey: String?
|
||||||
public var groupName: String = FormValidator.defaultGroupName
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
private var selectedRadioButton: RadioButton?
|
private var selectedRadioButton: RadioButton?
|
||||||
private var fieldGroupName: String?
|
private var selectedRadioButtonModel: RadioButtonModel?
|
||||||
public var baseValue: AnyHashable?
|
public var baseValue: AnyHashable?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializer
|
// MARK: - Initializer
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
init(_ fieldKey: String?) {
|
public func set(_ radioButtonModel: RadioButtonModel, _ radioButton: RadioButton) {
|
||||||
self.fieldKey = fieldKey
|
self.fieldKey = radioButtonModel.fieldKey
|
||||||
|
self.groupName = radioButtonModel.groupName
|
||||||
|
|
||||||
|
if radioButtonModel.state {
|
||||||
|
if self.baseValue == nil,
|
||||||
|
let selected = radioButtonModel.baseValue as? Bool, selected {
|
||||||
|
self.baseValue = radioButtonModel.fieldValue
|
||||||
|
}
|
||||||
|
selectedRadioButtonModel = radioButtonModel
|
||||||
|
|
||||||
|
// Below code is needed for cell resuse scenario.
|
||||||
|
radioButton.isSelected = true
|
||||||
|
selectedRadioButton = radioButton
|
||||||
|
} else {
|
||||||
|
radioButton.isSelected = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -35,35 +50,33 @@ import Foundation
|
|||||||
public static func setupForRadioButtonGroup(_ radioButtonModel: RadioButtonModel, _ radioButton: RadioButton, delegateObject: MVMCoreUIDelegateObject?) {
|
public static func setupForRadioButtonGroup(_ radioButtonModel: RadioButtonModel, _ radioButton: RadioButton, delegateObject: MVMCoreUIDelegateObject?) {
|
||||||
|
|
||||||
guard let groupName = radioButtonModel.fieldKey,
|
guard let groupName = radioButtonModel.fieldKey,
|
||||||
let formValidator = delegateObject?.formHolderDelegate?.formValidator
|
let formValidator = delegateObject?.formHolderDelegate?.formValidator else {
|
||||||
else { return }
|
return
|
||||||
|
|
||||||
let radioButtonSelectionHelper = formValidator.radioButtonsModelByGroup[groupName] ?? RadioButtonSelectionHelper(radioButtonModel.fieldKey)
|
|
||||||
radioButtonSelectionHelper.fieldGroupName = radioButtonModel.fieldKey
|
|
||||||
formValidator.radioButtonsModelByGroup[groupName] = radioButtonSelectionHelper
|
|
||||||
|
|
||||||
if radioButtonModel.state {
|
|
||||||
radioButtonSelectionHelper.selectedRadioButton = radioButton
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let radioButtonSelectionHelper = formValidator.radioButtonsModelByGroup[groupName] ?? RadioButtonSelectionHelper()
|
||||||
|
radioButtonSelectionHelper.set(radioButtonModel, radioButton)
|
||||||
|
formValidator.radioButtonsModelByGroup[groupName] = radioButtonSelectionHelper
|
||||||
FormValidator.setupValidation(for: radioButtonSelectionHelper, delegate: delegateObject?.formHolderDelegate)
|
FormValidator.setupValidation(for: radioButtonSelectionHelper, delegate: delegateObject?.formHolderDelegate)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func selected(_ radioButton: RadioButton) {
|
public func selected(_ radioButton: RadioButton) {
|
||||||
|
// Checks because the view could be reused
|
||||||
selectedRadioButton?.isSelected = false
|
if selectedRadioButton?.radioModel === selectedRadioButtonModel {
|
||||||
|
selectedRadioButton?.isSelected = false
|
||||||
|
} else {
|
||||||
|
selectedRadioButtonModel?.state = false
|
||||||
|
}
|
||||||
|
|
||||||
selectedRadioButton = radioButton
|
selectedRadioButton = radioButton
|
||||||
selectedRadioButton?.isSelected = true
|
selectedRadioButton?.isSelected = true
|
||||||
|
selectedRadioButtonModel = selectedRadioButton?.radioModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - FormValidationFormFieldProtocol
|
// MARK: - FormValidationFormFieldProtocol
|
||||||
extension RadioButtonSelectionHelper {
|
extension RadioButtonSelectionHelper {
|
||||||
|
|
||||||
public func formFieldGroupName() -> String? {
|
|
||||||
return selectedRadioButton?.formFieldGroupName() ?? fieldGroupName
|
|
||||||
}
|
|
||||||
|
|
||||||
public func formFieldValue() -> AnyHashable? {
|
public func formFieldValue() -> AnyHashable? {
|
||||||
return selectedRadioButton?.formFieldValue()
|
return selectedRadioButtonModel?.fieldValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -276,7 +276,7 @@ import UIKit
|
|||||||
let fallbackImageName = customFallbackImage ?? MVMCoreUIUtility.localizedImageName("fallback")
|
let fallbackImageName = customFallbackImage ?? MVMCoreUIUtility.localizedImageName("fallback")
|
||||||
if let format = format, format.lowercased().contains("gif") {
|
if let format = format, format.lowercased().contains("gif") {
|
||||||
// Gifs aren't supported by default and need special handling
|
// Gifs aren't supported by default and need special handling
|
||||||
MVMCoreCache.shared()?.getGif(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, completionHandler: finishedLoadingBlock)
|
MVMCoreCache.shared()?.getGif(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, localBundle: localBundle, completionHandler: finishedLoadingBlock)
|
||||||
} else {
|
} else {
|
||||||
MVMCoreCache.shared()?.getImage(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, localBundle: localBundle, completionHandler: finishedLoadingBlock)
|
MVMCoreCache.shared()?.getImage(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, localBundle: localBundle, completionHandler: finishedLoadingBlock)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,7 +47,7 @@ import Foundation
|
|||||||
// need to move labelattributemodel to different method
|
// need to move labelattributemodel to different method
|
||||||
try? ModelRegistry.register(LabelAttributeFontModel.self)
|
try? ModelRegistry.register(LabelAttributeFontModel.self)
|
||||||
try? ModelRegistry.register(LabelAttributeColorModel.self)
|
try? ModelRegistry.register(LabelAttributeColorModel.self)
|
||||||
try? ModelRegistry.register(LabelAttributeImageModel.self) // We need to separate the registry by types due to collisions...
|
try? ModelRegistry.register(LabelAttributeImageModel.self)
|
||||||
try? ModelRegistry.register(LabelAttributeUnderlineModel.self)
|
try? ModelRegistry.register(LabelAttributeUnderlineModel.self)
|
||||||
try? ModelRegistry.register(LabelAttributeStrikeThroughModel.self)
|
try? ModelRegistry.register(LabelAttributeStrikeThroughModel.self)
|
||||||
try? ModelRegistry.register(LabelAttributeActionModel.self)
|
try? ModelRegistry.register(LabelAttributeActionModel.self)
|
||||||
@ -66,6 +66,11 @@ import Foundation
|
|||||||
MoleculeObjectMapping.shared()?.register(viewClass: ItemDropdownEntryField.self, viewModelClass: ItemDropdownEntryFieldModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ItemDropdownEntryField.self, viewModelClass: ItemDropdownEntryFieldModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: DateDropdownEntryField.self, viewModelClass: DateDropdownEntryFieldModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: DateDropdownEntryField.self, viewModelClass: DateDropdownEntryFieldModel.self)
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: RadioBoxes.self, viewModelClass: RadioBoxesModel.self)
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self)
|
||||||
|
|
||||||
// Other Atoms
|
// Other Atoms
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self)
|
||||||
@ -75,10 +80,8 @@ import Foundation
|
|||||||
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: GraphView.self, viewModelClass: CircleProgressModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.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)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self)
|
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: RadioButtonLabel.self, viewModelClass: RadioButtonLabelModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: RadioButtonLabel.self, viewModelClass: RadioButtonLabelModel.self)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: WebView.self, viewModelClass: WebViewModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: WebView.self, viewModelClass: WebViewModel.self)
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import UIKit
|
|||||||
|
|
||||||
open class Carousel: View {
|
open class Carousel: View {
|
||||||
|
|
||||||
public let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
|
public let collectionView = CollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
|
||||||
|
|
||||||
/// The current index of the collection view. Includes dummy cells when looping.
|
/// The current index of the collection view. Includes dummy cells when looping.
|
||||||
public var currentIndex = 0
|
public var currentIndex = 0
|
||||||
@ -83,12 +83,8 @@ open class Carousel: View {
|
|||||||
// MARK: - MVMCoreViewProtocol
|
// MARK: - MVMCoreViewProtocol
|
||||||
open override func setupView() {
|
open override func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
collectionView.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
collectionView.dataSource = self
|
collectionView.dataSource = self
|
||||||
collectionView.delegate = self
|
collectionView.delegate = self
|
||||||
collectionView.showsHorizontalScrollIndicator = false
|
|
||||||
collectionView.backgroundColor = .clear
|
|
||||||
collectionView.isAccessibilityElement = false
|
|
||||||
addSubview(collectionView)
|
addSubview(collectionView)
|
||||||
bottomPin = NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView)?[ConstraintBot] as? NSLayoutConstraint
|
bottomPin = NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView)?[ConstraintBot] as? NSLayoutConstraint
|
||||||
|
|
||||||
|
|||||||
47
MVMCoreUI/BaseClasses/CollectionView.swift
Normal file
47
MVMCoreUI/BaseClasses/CollectionView.swift
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// CollectionView.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 4/10/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class CollectionView: UICollectionView, MVMCoreViewProtocol {
|
||||||
|
|
||||||
|
private var initialSetupPerformed = false
|
||||||
|
|
||||||
|
private func initialSetup() {
|
||||||
|
if !initialSetupPerformed {
|
||||||
|
initialSetupPerformed = true
|
||||||
|
setupView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
|
||||||
|
super.init(frame: frame, collectionViewLayout: layout)
|
||||||
|
initialSetup()
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
initialSetup()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateView(_ size: CGFloat) {
|
||||||
|
for cell in visibleCells {
|
||||||
|
(cell as? MVMCoreViewProtocol)?.updateView(size)
|
||||||
|
}
|
||||||
|
collectionViewLayout.invalidateLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setupView() {
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
showsHorizontalScrollIndicator = false
|
||||||
|
showsVerticalScrollIndicator = false
|
||||||
|
backgroundColor = .clear
|
||||||
|
isAccessibilityElement = false
|
||||||
|
contentInsetAdjustmentBehavior = .always
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -46,14 +46,9 @@ import Foundation
|
|||||||
|
|
||||||
/// Creates the collection view.
|
/// Creates the collection view.
|
||||||
open func createCollectionView() -> UICollectionView {
|
open func createCollectionView() -> UICollectionView {
|
||||||
let collection = UICollectionView(frame: .zero, collectionViewLayout: createCollectionViewLayout())
|
let collection = CollectionView(frame: .zero, collectionViewLayout: createCollectionViewLayout())
|
||||||
collection.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
collection.dataSource = self
|
collection.dataSource = self
|
||||||
collection.delegate = self
|
collection.delegate = self
|
||||||
collection.showsHorizontalScrollIndicator = false
|
|
||||||
collection.backgroundColor = .white
|
|
||||||
collection.isAccessibilityElement = false
|
|
||||||
collection.contentInsetAdjustmentBehavior = .always
|
|
||||||
return collection
|
return collection
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -74,12 +74,13 @@ import MVMCore
|
|||||||
/// Validates all rule groups. Returns if valid
|
/// Validates all rule groups. Returns if valid
|
||||||
public func validate() -> Bool {
|
public func validate() -> Bool {
|
||||||
var valid = true
|
var valid = true
|
||||||
guard let formRules = formRules else {
|
guard let formRules = formRules else { return valid }
|
||||||
return valid
|
|
||||||
}
|
|
||||||
for group in formRules {
|
for group in formRules {
|
||||||
valid = valid && validateGroup(group)
|
let groupValid = validateGroup(group)
|
||||||
|
valid = valid && groupValid
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid
|
return valid
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,13 +125,16 @@ import MVMCore
|
|||||||
|
|
||||||
// TODO: Temporary hacks, rewrite architecture to support this.
|
// TODO: Temporary hacks, rewrite architecture to support this.
|
||||||
public extension FormValidator {
|
public extension FormValidator {
|
||||||
|
|
||||||
func getGroupName(forPageType pageType: String?) -> String? {
|
func getGroupName(forPageType pageType: String?) -> String? {
|
||||||
|
|
||||||
for actionItem in groupWatchers {
|
for actionItem in groupWatchers {
|
||||||
if let buttonModel = actionItem as? ButtonModel,
|
if let buttonModel = actionItem as? ButtonModel,
|
||||||
pageType == (buttonModel.action as? ActionOpenPageModel)?.pageType {
|
pageType == (buttonModel.action as? ActionOpenPageModel)?.pageType {
|
||||||
return buttonModel.groupName
|
return buttonModel.groupName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,19 +11,35 @@ import Foundation
|
|||||||
|
|
||||||
|
|
||||||
open class FormGroupRule: Codable {
|
open class FormGroupRule: Codable {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
var groupName: String
|
var groupName: String
|
||||||
var rules: [RulesProtocol]
|
var rules: [RulesProtocol]
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializer
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
init(_ groupName: String, _ rules: [RulesProtocol]) {
|
init(_ groupName: String, _ rules: [RulesProtocol]) {
|
||||||
self.groupName = groupName
|
self.groupName = groupName
|
||||||
self.rules = rules
|
self.rules = rules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Keys
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case groupName
|
case groupName
|
||||||
case rules
|
case rules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// 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)
|
||||||
self.groupName = try typeContainer.decode(String.self, forKey: .groupName)
|
self.groupName = try typeContainer.decode(String.self, forKey: .groupName)
|
||||||
|
|||||||
@ -9,11 +9,18 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public class RuleAllValueChangedModel: RulesProtocol {
|
public class RuleAllValueChangedModel: RulesProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public static var identifier: String = "allValueChanged"
|
public static var identifier: String = "allValueChanged"
|
||||||
public var type: String = RuleAllValueChangedModel.identifier
|
public var type: String = RuleAllValueChangedModel.identifier
|
||||||
public var fields: [String]
|
public var fields: [String]
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Validation
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public func isValid(_ formField: FormFieldProtocol) -> Bool {
|
public func isValid(_ formField: FormFieldProtocol) -> Bool {
|
||||||
return formField.baseValue != formField.formFieldValue()
|
return formField.baseValue != formField.formFieldValue()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,9 +10,17 @@ import Foundation
|
|||||||
|
|
||||||
|
|
||||||
public class RuleEqualsModel: RulesProtocol {
|
public class RuleEqualsModel: RulesProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public static var identifier: String = "equals"
|
public static var identifier: String = "equals"
|
||||||
public var type: String = RuleEqualsModel.identifier
|
public var type: String = RuleEqualsModel.identifier
|
||||||
public var fields: [String]
|
public var fields: [String]
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Validation
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public func isValid(_ formField: FormFieldProtocol) -> Bool {
|
public func isValid(_ formField: FormFieldProtocol) -> Bool {
|
||||||
return false
|
return false
|
||||||
@ -21,20 +29,21 @@ public class RuleEqualsModel: RulesProtocol {
|
|||||||
public func validate(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool {
|
public func validate(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool {
|
||||||
var valid = true
|
var valid = true
|
||||||
var compareValue: AnyHashable?
|
var compareValue: AnyHashable?
|
||||||
|
|
||||||
for formKey in fields {
|
for formKey in fields {
|
||||||
guard let formField = fieldMolecules[formKey] else {
|
guard let formField = fieldMolecules[formKey] else { continue }
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if compareValue == nil {
|
if compareValue == nil {
|
||||||
compareValue = formField.formFieldValue()
|
compareValue = formField.formFieldValue()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if compareValue != formField.formFieldValue(){
|
|
||||||
|
if compareValue != formField.formFieldValue() {
|
||||||
valid = false
|
valid = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid
|
return valid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,16 +8,27 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
public class RuleRegexModel: RulesProtocol {
|
public class RuleRegexModel: RulesProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public static var identifier: String = "regex"
|
public static var identifier: String = "regex"
|
||||||
public var type: String = RuleRegexModel.identifier
|
public var type: String = RuleRegexModel.identifier
|
||||||
public var fields: [String]
|
public var fields: [String]
|
||||||
public var regex: String
|
public var regex: String
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public func isValid(_ formField: FormFieldProtocol) -> Bool {
|
public func isValid(_ formField: FormFieldProtocol) -> Bool {
|
||||||
|
|
||||||
if let stringToValidate = formField.formFieldValue() as? String {
|
if let stringToValidate = formField.formFieldValue() as? String {
|
||||||
return MVMCoreUIUtility.validate(stringToValidate, withRegularExpression: regex)
|
return MVMCoreUIUtility.validate(stringToValidate, withRegularExpression: regex)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,21 +10,30 @@ import Foundation
|
|||||||
|
|
||||||
|
|
||||||
public class RuleRequiredModel: RulesProtocol {
|
public class RuleRequiredModel: RulesProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public static var identifier: String = "allRequired"
|
public static var identifier: String = "allRequired"
|
||||||
public var type: String = RuleRequiredModel.identifier
|
public var type: String = RuleRequiredModel.identifier
|
||||||
public var fields: [String]
|
public var fields: [String]
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Validation
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public func isValid(_ formField: FormFieldProtocol) -> Bool {
|
public func isValid(_ formField: FormFieldProtocol) -> Bool {
|
||||||
guard let value = formField.formFieldValue() else {
|
guard let value = formField.formFieldValue() else { return false }
|
||||||
return false
|
|
||||||
}
|
|
||||||
var valid = true
|
var valid = true
|
||||||
|
|
||||||
if let valueString = value as? String {
|
if let valueString = value as? String {
|
||||||
valid = valueString.count > 0
|
valid = valueString.count > 0
|
||||||
|
|
||||||
} else if let valueBool = value as? Bool {
|
} else if let valueBool = value as? Bool {
|
||||||
valid = valueBool
|
valid = valueBool
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid
|
return valid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user