Merge branch 'develop' into feature/list_device_complex_link_medium
# Conflicts: # MVMCoreUI.xcodeproj/project.pbxproj
This commit is contained in:
commit
e34e859aa1
@ -94,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 */; };
|
||||||
@ -102,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 */; };
|
||||||
@ -142,6 +145,8 @@
|
|||||||
8D8067D32444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D8067D22444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.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 */; };
|
||||||
@ -201,6 +206,8 @@
|
|||||||
AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; };
|
AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; };
|
||||||
AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatch.swift */; };
|
AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatch.swift */; };
|
||||||
AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.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 */; };
|
||||||
@ -531,6 +538,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>"; };
|
||||||
@ -541,6 +549,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>"; };
|
||||||
@ -581,6 +591,8 @@
|
|||||||
8D8067D22444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePriceChangeAllTextAndLinks.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>"; };
|
||||||
@ -639,6 +651,8 @@
|
|||||||
AAB9C10724346F4B00151545 /* RadioSwatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatches.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>"; };
|
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>"; };
|
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>"; };
|
||||||
@ -1069,6 +1083,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>";
|
||||||
@ -1153,6 +1169,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>";
|
||||||
@ -1166,6 +1185,15 @@
|
|||||||
path = FourColumn;
|
path = FourColumn;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
D20FFFB42451E32100A31DA2 /* Device */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */,
|
||||||
|
BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */,
|
||||||
|
);
|
||||||
|
path = Device;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
D213347423842FE3008E41B3 /* Controllers */ = {
|
D213347423842FE3008E41B3 /* Controllers */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -1364,6 +1392,7 @@
|
|||||||
D22B38EA23F4E08B00490EF6 /* List */ = {
|
D22B38EA23F4E08B00490EF6 /* List */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
D20FFFB42451E32100A31DA2 /* Device */,
|
||||||
AA2AD114244EE43900BBFFE3 /* DeviceItems */,
|
AA2AD114244EE43900BBFFE3 /* DeviceItems */,
|
||||||
52267A0523FFE0A900906CBA /* OneColumn */,
|
52267A0523FFE0A900906CBA /* OneColumn */,
|
||||||
D22D8396241FDE4700D3DF69 /* TwoColumn */,
|
D22D8396241FDE4700D3DF69 /* TwoColumn */,
|
||||||
@ -2164,6 +2193,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 */,
|
||||||
@ -2199,6 +2229,7 @@
|
|||||||
014AA72623C501E2006F3E93 /* ContainerModelProtocol.swift in Sources */,
|
014AA72623C501E2006F3E93 /* ContainerModelProtocol.swift in Sources */,
|
||||||
AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */,
|
AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.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 */,
|
||||||
@ -2207,6 +2238,7 @@
|
|||||||
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 */,
|
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 */,
|
||||||
@ -2238,6 +2270,7 @@
|
|||||||
AA69AAF82445BF6800AF3D3B /* ListLeftVariableCheckboxBodyTextModel.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 */,
|
||||||
525019E52406852100EED91C /* ListFourColumnDataUsageDividerModel.swift in Sources */,
|
525019E52406852100EED91C /* ListFourColumnDataUsageDividerModel.swift in Sources */,
|
||||||
0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */,
|
0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */,
|
||||||
@ -2343,6 +2376,7 @@
|
|||||||
012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */,
|
012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */,
|
||||||
D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */,
|
D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m 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 */,
|
||||||
C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */,
|
C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */,
|
||||||
@ -2408,6 +2442,7 @@
|
|||||||
D21B7F73243BAC6800051ABF /* CollectionItemModelProtocol.swift in Sources */,
|
D21B7F73243BAC6800051ABF /* CollectionItemModelProtocol.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 */,
|
||||||
@ -2424,6 +2459,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,6 +9,7 @@
|
|||||||
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
|
||||||
public var extraParameters: JSONValueDictionary?
|
public var extraParameters: JSONValueDictionary?
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
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
|
||||||
|
|||||||
@ -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,12 +31,12 @@ 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
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -48,14 +48,6 @@ import UIKit
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
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,7 +252,6 @@ import UIKit
|
|||||||
|
|
||||||
title = model.title
|
title = model.title
|
||||||
feedback = model.feedback
|
feedback = model.feedback
|
||||||
errorMessage = model.errorMessage
|
|
||||||
isEnabled = model.enabled
|
isEnabled = model.enabled
|
||||||
|
|
||||||
if let isLocked = model.locked {
|
if let isLocked = model.locked {
|
||||||
|
|||||||
@ -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 enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
public var locked: Bool?
|
public var locked: Bool?
|
||||||
public var selected: 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
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -62,11 +55,19 @@ import Foundation
|
|||||||
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
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -76,17 +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)
|
||||||
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||||
locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked)
|
locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked)
|
||||||
selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected)
|
selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected)
|
||||||
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) {
|
||||||
@ -100,11 +104,11 @@ 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(enabled, forKey: .enabled)
|
|
||||||
try container.encode(locked, forKey: .locked)
|
|
||||||
try container.encode(selected, forKey: .selected)
|
|
||||||
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(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,37 +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
|
||||||
}
|
}
|
||||||
|
|
||||||
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,8 +28,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
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?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -34,7 +38,6 @@
|
|||||||
|
|
||||||
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
|
||||||
@ -42,27 +45,31 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// 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)
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -131,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)
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -189,6 +207,8 @@ 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() {
|
||||||
@ -218,9 +238,7 @@ 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() {
|
||||||
@ -228,9 +246,8 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
|
|
||||||
backgroundColor = containerTintColor.off
|
backgroundColor = containerTintColor.off
|
||||||
knobView.backgroundColor = knobTintColor.off
|
knobView.backgroundColor = knobTintColor.off
|
||||||
|
accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel")
|
||||||
isAnimated = true
|
isAnimated = true
|
||||||
isOn = false
|
|
||||||
constrainKnob()
|
|
||||||
didToggleAction = nil
|
didToggleAction = nil
|
||||||
shouldToggleAction = { return true }
|
shouldToggleAction = { return true }
|
||||||
}
|
}
|
||||||
@ -352,10 +369,15 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
containerTintColor.off = model.offTintColor.uiColor
|
containerTintColor.off = model.offTintColor.uiColor
|
||||||
knobTintColor.on = model.onKnobTintColor.uiColor
|
knobTintColor.on = model.onKnobTintColor.uiColor
|
||||||
knobTintColor.off = model.offKnobTintColor.uiColor
|
knobTintColor.off = model.offKnobTintColor.uiColor
|
||||||
changeStateNoAnimation(model.state)
|
isOn = model.state
|
||||||
|
changeStateNoAnimation(isOn)
|
||||||
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) }
|
||||||
}
|
}
|
||||||
|
|||||||
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -150,6 +150,7 @@ import Foundation
|
|||||||
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)
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkMedium.self, viewModelClass: ListDeviceComplexLinkMediumModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkMedium.self, viewModelClass: ListDeviceComplexLinkMediumModel.self)
|
||||||
|
|
||||||
@ -167,6 +168,10 @@ import Foundation
|
|||||||
|
|
||||||
// Designed Headers
|
// Designed Headers
|
||||||
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2NoButtonsBodyText.self, viewModelClass: HeadersH2NoButtonsBodyTextModel.self)
|
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2NoButtonsBodyText.self, viewModelClass: HeadersH2NoButtonsBodyTextModel.self)
|
||||||
|
|
||||||
|
|
||||||
|
// Device Items
|
||||||
|
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonMedium.self, viewModelClass: ListDeviceComplexButtonMediumModel.self)
|
||||||
|
|
||||||
// TODO: Need View
|
// TODO: Need View
|
||||||
try? ModelRegistry.register(TabsModel.self)
|
try? ModelRegistry.register(TabsModel.self)
|
||||||
|
|||||||
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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? {
|
||||||
|
|||||||
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -17,6 +17,7 @@ import Foundation
|
|||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
|
case backgroundColor
|
||||||
case spacing
|
case spacing
|
||||||
case percent
|
case percent
|
||||||
case gone
|
case gone
|
||||||
@ -33,6 +34,7 @@ import Foundation
|
|||||||
if let gone = try typeContainer.decodeIfPresent(Bool.self, forKey: .gone) {
|
if let gone = try typeContainer.decodeIfPresent(Bool.self, forKey: .gone) {
|
||||||
self.gone = gone
|
self.gone = gone
|
||||||
}
|
}
|
||||||
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,5 +45,6 @@ import Foundation
|
|||||||
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)
|
||||||
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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? {
|
||||||
|
|||||||
@ -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
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -48,6 +48,7 @@ import Foundation
|
|||||||
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)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,5 +59,6 @@ import Foundation
|
|||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,7 @@ open class ScrollingViewController: ViewController {
|
|||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
// Adds the tap gesture to dismiss the keyboard.
|
// Adds the tap gesture to dismiss the keyboard.
|
||||||
dismissKeyboardTapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissFieldInput(sender:)))
|
dismissKeyboardTapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissFieldInput))
|
||||||
view.addGestureRecognizer(dismissKeyboardTapGesture!)
|
view.addGestureRecognizer(dismissKeyboardTapGesture!)
|
||||||
dismissKeyboardTapGesture?.isEnabled = false
|
dismissKeyboardTapGesture?.isEnabled = false
|
||||||
scrollView.alwaysBounceVertical = false
|
scrollView.alwaysBounceVertical = false
|
||||||
|
|||||||
@ -405,7 +405,7 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc open func dismissFieldInput(sender: Any?) {
|
@objc open func dismissFieldInput(_ sender: Any?) {
|
||||||
selectedField?.resignFirstResponder()
|
selectedField?.resignFirstResponder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,9 +25,7 @@ import UIKit
|
|||||||
|
|
||||||
/// Total control over the drawn top, bottom, left and right borders.
|
/// Total control over the drawn top, bottom, left and right borders.
|
||||||
public var disableAllBorders = false {
|
public var disableAllBorders = false {
|
||||||
didSet {
|
didSet { bottomBar?.isHidden = disableAllBorders }
|
||||||
bottomBar?.isHidden = disableAllBorders
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private(set) var fieldState: FieldState = .original {
|
private(set) var fieldState: FieldState = .original {
|
||||||
|
|||||||
@ -10,10 +10,8 @@ import Foundation
|
|||||||
|
|
||||||
|
|
||||||
open class Styler {
|
open class Styler {
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Enums
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
|
// MARK:- Font Enum
|
||||||
public enum Font: String, Codable {
|
public enum Font: String, Codable {
|
||||||
case Title2XLarge
|
case Title2XLarge
|
||||||
case TitleXLarge
|
case TitleXLarge
|
||||||
|
|||||||
23
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/Contents.json
vendored
Normal file
23
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "alert_standard @1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "alert_standard @2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "alert_standard @3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @1x.png
vendored
Normal file
BIN
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @1x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 279 B |
BIN
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @2x.png
vendored
Normal file
BIN
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 525 B |
BIN
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @3x.png
vendored
Normal file
BIN
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 771 B |
@ -198,7 +198,7 @@
|
|||||||
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|->=space-[button]->=space-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"space":@(PaddingFive)} views:NSDictionaryOfVariableBindings(button)]];
|
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|->=space-[button]->=space-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"space":@(PaddingFive)} views:NSDictionaryOfVariableBindings(button)]];
|
||||||
[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0].active = YES;
|
[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0].active = YES;
|
||||||
[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.centerView attribute:NSLayoutAttributeRight multiplier:1 constant:PaddingThree].active = YES;
|
[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.centerView attribute:NSLayoutAttributeRight multiplier:1 constant:PaddingThree].active = YES;
|
||||||
[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:button attribute:NSLayoutAttributeRight multiplier:1 constant:(self.closeButton ? PaddingTen : PaddingThree)].active = YES;
|
[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:button attribute:NSLayoutAttributeRight multiplier:1 constant:(self.closeButton ? PaddingTen : PaddingFive)].active = YES;
|
||||||
self.button = button;
|
self.button = button;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -210,7 +210,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!self.labelRightConstraint) {
|
if (!self.labelRightConstraint) {
|
||||||
self.labelRightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.centerView attribute:NSLayoutAttributeRight multiplier:1 constant:(self.closeButton ? PaddingTen : PaddingThree)];
|
self.labelRightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.centerView attribute:NSLayoutAttributeRight multiplier:1 constant:(self.closeButton ? PaddingTen : PaddingFive)];
|
||||||
}
|
}
|
||||||
self.labelRightConstraint.active = YES;
|
self.labelRightConstraint.active = YES;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ public extension MVMCoreUICommonViewsUtility {
|
|||||||
|
|
||||||
let toolbar = self.makeEmptyToolbar()
|
let toolbar = self.makeEmptyToolbar()
|
||||||
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
||||||
let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: #selector(ObservingTextFieldDelegate.dismissFieldInput(sender:)))
|
let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: #selector(ObservingTextFieldDelegate.dismissFieldInput))
|
||||||
button.tintColor = .black
|
button.tintColor = .black
|
||||||
toolbar.setItems([space, button], animated: false)
|
toolbar.setItems([space, button], animated: false)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user