diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 56b0c33f..a26ef5f6 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -12,9 +12,10 @@ 0105618D224BBE7700E1557D /* FormValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618A224BBE7700E1557D /* FormValidator.swift */; }; 0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */; }; 0105618F224BBE7700E1557D /* FormValidator+FormParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */; }; - 0116A4E5228B19640094F3ED /* RadioButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0116A4E4228B19640094F3ED /* RadioButtonModel.swift */; }; + 0116A4E5228B19640094F3ED /* RadioButtonSelectionHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */; }; 011B58F023A2AA980085F53C /* ListItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */; }; 011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011B58F123A2AE2C0085F53C /* DropDownListItemModel.swift */; }; + 011D95AF2407266E000E3791 /* RadioButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95AE2407266E000E3791 /* RadioButtonModel.swift */; }; 012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A889B23889E8400FE3DA1 /* TemplateModelProtocol.swift */; }; 012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88AC238C418100FE3DA1 /* TemplateProtocol.swift */; }; 012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88B0238C880100FE3DA1 /* CarouselPagingModelProtocol.swift */; }; @@ -94,6 +95,10 @@ 0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; }; 0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; }; 0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; }; + 0AE98BAF23FEF956004C5109 /* ExternalLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BAE23FEF956004C5109 /* ExternalLink.swift */; }; + 0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB223FF0934004C5109 /* ExternalLinkModel.swift */; }; + 0AE98BB523FF18D2004C5109 /* Arrow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB423FF18D2004C5109 /* Arrow.swift */; }; + 0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB623FF18E9004C5109 /* ArrowModel.swift */; }; 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; }; 31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; }; 522679C123FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */; }; @@ -103,6 +108,10 @@ 5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */; }; 525019DD2406430800EED91C /* ListProgressBarDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525019DB2406430700EED91C /* ListProgressBarDataModel.swift */; }; 525019DE2406430800EED91C /* ListProgressBarData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525019DC2406430800EED91C /* ListProgressBarData.swift */; }; + 525019E52406852100EED91C /* ListFourColumnDataUsageDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525019E42406852100EED91C /* ListFourColumnDataUsageDividerModel.swift */; }; + 525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525019E62406853600EED91C /* ListFourColumnDataUsageDivider.swift */; }; + 52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */; }; + 52B201D324081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */; }; 8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */; }; 8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */; }; 8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */; }; @@ -115,6 +124,8 @@ 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 944589202385D6E900DE9FD4 /* DashLineModel.swift */; }; 944589232385DA9600DE9FD4 /* ImageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 944589222385DA9500DE9FD4 /* ImageViewModel.swift */; }; 9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; }; + 9458C3172406C8FD00930963 /* UIFont+FontWrapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 9458C3152406C8FD00930963 /* UIFont+FontWrapping.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9458C3182406C8FD00930963 /* UIFont+FontWrapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 9458C3162406C8FD00930963 /* UIFont+FontWrapping.m */; }; 946EE1BA237B66D80036751F /* MoleculeModelHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1B9237B66D80036751F /* MoleculeModelHelper.swift */; }; 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; }; 94AF4A3E23E9D13900676048 /* MFCaretButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 94AF4A3C23E9D13900676048 /* MFCaretButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -130,6 +141,10 @@ 94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9AA23872EB50006CF46 /* LabelAttributeActionModel.swift */; }; 94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */; }; 94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B33239813C50067DD0F /* UIColor+Extension.swift */; }; + 94CA227C24058534002D6750 /* VerizonNHGeTX-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227824058533002D6750 /* VerizonNHGeTX-Bold.otf */; }; + 94CA227D24058534002D6750 /* VerizonNHGeDS-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227924058533002D6750 /* VerizonNHGeDS-Regular.otf */; }; + 94CA227E24058534002D6750 /* VerizonNHGeDS-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227A24058533002D6750 /* VerizonNHGeDS-Bold.otf */; }; + 94CA227F24058534002D6750 /* VerizonNHGeTX-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227B24058533002D6750 /* VerizonNHGeTX-Regular.otf */; }; 94F217B623E0BF6100A47C06 /* PrimaryButtonView.h in Headers */ = {isa = PBXBuildFile; fileRef = 94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 94F217B723E0BF6100A47C06 /* PrimaryButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */; }; 94FB966223D797DA003D482B /* MFTextButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 94FB966023D797DA003D482B /* MFTextButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -292,10 +307,7 @@ D29DF2E121E9240B003B2FB9 /* MVMCoreUIPanelProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF2E021E9240B003B2FB9 /* MVMCoreUIPanelProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF2EE21ECEADF003B2FB9 /* MFFonts.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF14D21E693AD003B2FB9 /* MFFonts.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF2EF21ECEAE1003B2FB9 /* MFFonts.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF14C21E693AD003B2FB9 /* MFFonts.m */; }; - D29DF31A21ECECC0003B2FB9 /* NHaasGroteskDSStd-45Lt.otf in Resources */ = {isa = PBXBuildFile; fileRef = D29DF31621ECECC0003B2FB9 /* NHaasGroteskDSStd-45Lt.otf */; }; D29DF31B21ECECC0003B2FB9 /* OCRAExtended.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D29DF31721ECECC0003B2FB9 /* OCRAExtended.ttf */; }; - D29DF31C21ECECC0003B2FB9 /* NHaasGroteskDSStd-75Bd.otf in Resources */ = {isa = PBXBuildFile; fileRef = D29DF31821ECECC0003B2FB9 /* NHaasGroteskDSStd-75Bd.otf */; }; - D29DF31D21ECECC0003B2FB9 /* NHaasGroteskDSStd-55Rg.otf in Resources */ = {isa = PBXBuildFile; fileRef = D29DF31921ECECC0003B2FB9 /* NHaasGroteskDSStd-55Rg.otf */; }; D29DF32021ED0CBA003B2FB9 /* LabelView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF31E21ED0CBA003B2FB9 /* LabelView.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF31F21ED0CBA003B2FB9 /* LabelView.m */; }; D29DF32421ED0DA2003B2FB9 /* TextButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF32221ED0DA2003B2FB9 /* TextButtonView.m */; }; @@ -357,9 +369,10 @@ 0105618A224BBE7700E1557D /* FormValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidator.swift; sourceTree = ""; }; 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+TextFields.swift"; sourceTree = ""; }; 0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+FormParams.swift"; sourceTree = ""; }; - 0116A4E4228B19640094F3ED /* RadioButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonModel.swift; sourceTree = ""; }; + 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonSelectionHelper.swift; sourceTree = ""; }; 011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemModelProtocol.swift; sourceTree = ""; }; 011B58F123A2AE2C0085F53C /* DropDownListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropDownListItemModel.swift; sourceTree = ""; }; + 011D95AE2407266E000E3791 /* RadioButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonModel.swift; sourceTree = ""; }; 012A889B23889E8400FE3DA1 /* TemplateModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateModelProtocol.swift; sourceTree = ""; }; 012A88AC238C418100FE3DA1 /* TemplateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateProtocol.swift; sourceTree = ""; }; 012A88AE238C626E00FE3DA1 /* CarouselModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselModel.swift; sourceTree = ""; }; @@ -430,6 +443,10 @@ 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = ""; }; 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = ""; }; 0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = ""; }; + 0AE98BAE23FEF956004C5109 /* ExternalLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalLink.swift; sourceTree = ""; }; + 0AE98BB223FF0934004C5109 /* ExternalLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalLinkModel.swift; sourceTree = ""; }; + 0AE98BB423FF18D2004C5109 /* Arrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arrow.swift; sourceTree = ""; }; + 0AE98BB623FF18E9004C5109 /* ArrowModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrowModel.swift; sourceTree = ""; }; 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = ""; }; 31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = ""; }; 522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxAllTextAndLinks.swift; sourceTree = ""; }; @@ -439,6 +456,10 @@ 5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnPlanDataDividerModel.swift; sourceTree = ""; }; 525019DB2406430700EED91C /* ListProgressBarDataModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListProgressBarDataModel.swift; sourceTree = ""; }; 525019DC2406430800EED91C /* ListProgressBarData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListProgressBarData.swift; sourceTree = ""; }; + 525019E42406852100EED91C /* ListFourColumnDataUsageDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageDividerModel.swift; sourceTree = ""; }; + 525019E62406853600EED91C /* ListFourColumnDataUsageDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageDivider.swift; sourceTree = ""; }; + 52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAndPaymentMethod.swift; sourceTree = ""; }; + 52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAndPaymentMethodModel.swift; sourceTree = ""; }; 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaret.swift; sourceTree = ""; }; 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretModel.swift; sourceTree = ""; }; 8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextAllTextAndLinksModel.swift; sourceTree = ""; }; @@ -452,6 +473,8 @@ 944589202385D6E900DE9FD4 /* DashLineModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashLineModel.swift; sourceTree = ""; }; 944589222385DA9500DE9FD4 /* ImageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageViewModel.swift; sourceTree = ""; }; 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = ""; }; + 9458C3152406C8FD00930963 /* UIFont+FontWrapping.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIFont+FontWrapping.h"; sourceTree = ""; }; + 9458C3162406C8FD00930963 /* UIFont+FontWrapping.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIFont+FontWrapping.m"; sourceTree = ""; }; 946EE1B9237B66D80036751F /* MoleculeModelHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeModelHelper.swift; sourceTree = ""; }; 948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = ""; }; 94AF4A3C23E9D13900676048 /* MFCaretButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MFCaretButton.h; sourceTree = ""; }; @@ -465,6 +488,10 @@ 94C2D9A623872DA90006CF46 /* LabelAttributeColorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeColorModel.swift; sourceTree = ""; }; 94C2D9A823872E5E0006CF46 /* LabelAttributeImageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeImageModel.swift; sourceTree = ""; }; 94C2D9AA23872EB50006CF46 /* LabelAttributeActionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeActionModel.swift; sourceTree = ""; }; + 94CA227824058533002D6750 /* VerizonNHGeTX-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeTX-Bold.otf"; sourceTree = ""; }; + 94CA227924058533002D6750 /* VerizonNHGeDS-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeDS-Regular.otf"; sourceTree = ""; }; + 94CA227A24058533002D6750 /* VerizonNHGeDS-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeDS-Bold.otf"; sourceTree = ""; }; + 94CA227B24058533002D6750 /* VerizonNHGeTX-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeTX-Regular.otf"; sourceTree = ""; }; 94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrimaryButtonView.h; sourceTree = ""; }; 94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PrimaryButtonView.m; sourceTree = ""; }; 94FB966023D797DA003D482B /* MFTextButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFTextButton.h; sourceTree = ""; }; @@ -639,10 +666,7 @@ D29DF2CC21E7C104003B2FB9 /* MFLoadingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFLoadingViewController.h; sourceTree = ""; }; D29DF2CD21E7C104003B2FB9 /* MFLoadingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFLoadingViewController.m; sourceTree = ""; }; D29DF2E021E9240B003B2FB9 /* MVMCoreUIPanelProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIPanelProtocol.h; sourceTree = ""; }; - D29DF31621ECECC0003B2FB9 /* NHaasGroteskDSStd-45Lt.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NHaasGroteskDSStd-45Lt.otf"; sourceTree = ""; }; D29DF31721ECECC0003B2FB9 /* OCRAExtended.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = OCRAExtended.ttf; sourceTree = ""; }; - D29DF31821ECECC0003B2FB9 /* NHaasGroteskDSStd-75Bd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NHaasGroteskDSStd-75Bd.otf"; sourceTree = ""; }; - D29DF31921ECECC0003B2FB9 /* NHaasGroteskDSStd-55Rg.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NHaasGroteskDSStd-55Rg.otf"; sourceTree = ""; }; D29DF31E21ED0CBA003B2FB9 /* LabelView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LabelView.h; sourceTree = ""; }; D29DF31F21ED0CBA003B2FB9 /* LabelView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LabelView.m; sourceTree = ""; }; D29DF32221ED0DA2003B2FB9 /* TextButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TextButtonView.m; sourceTree = ""; }; @@ -776,6 +800,17 @@ path = Views; sourceTree = ""; }; + 0AE98BAD23FEF92B004C5109 /* Link */ = { + isa = PBXGroup; + children = ( + D28A838823CCCFCB00DFE4FC /* LinkModel.swift */, + C07065C32395677300FBF997 /* Link.swift */, + 0AE98BB223FF0934004C5109 /* ExternalLinkModel.swift */, + 0AE98BAE23FEF956004C5109 /* ExternalLink.swift */, + ); + path = Link; + sourceTree = ""; + }; 52267A0523FFE0A900906CBA /* OneColumn */ = { isa = PBXGroup; children = ( @@ -794,6 +829,15 @@ path = LockUps; sourceTree = ""; }; + 525019E3240684E500EED91C /* FourColumn */ = { + isa = PBXGroup; + children = ( + 525019E42406852100EED91C /* ListFourColumnDataUsageDividerModel.swift */, + 525019E62406853600EED91C /* ListFourColumnDataUsageDivider.swift */, + ); + path = FourColumn; + sourceTree = ""; + }; 946EE1B5237B663A0036751F /* Extensions */ = { isa = PBXGroup; children = ( @@ -1018,6 +1062,7 @@ D22B38EA23F4E08B00490EF6 /* List */ = { isa = PBXGroup; children = ( + 52267A0523FFE0A900906CBA /* OneColumn */, AA4FC2A323F4F69600E251DB /* RightVariable */, D22B38EB23F4E0AE00490EF6 /* LeftVariable */, ); @@ -1027,6 +1072,8 @@ D22B38EB23F4E0AE00490EF6 /* LeftVariable */ = { isa = PBXGroup; children = ( + 52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */, + 52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */, 522679C023FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift */, 522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */, 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */, @@ -1038,7 +1085,7 @@ D22B38EC23F4E10700490EF6 /* SectionDividers */ = { isa = PBXGroup; children = ( - 52267A0523FFE0A900906CBA /* OneColumn */, + 525019E3240684E500EED91C /* FourColumn */, D22B38ED23F4E11100490EF6 /* ThreeColumn */, ); path = SectionDividers; @@ -1165,7 +1212,7 @@ D2A514662213885800345BFB /* MoleculeHeaderView.swift */, 012A88EB238F084D00FE3DA1 /* FooterModel.swift */, D274CA322236A78900B01B62 /* FooterView.swift */, - 0116A4E4228B19640094F3ED /* RadioButtonModel.swift */, + 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */, 012A88C5238DA34000FE3DA1 /* ModuleMoleculeModel.swift */, D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */, D28A838423CCCA8900DFE4FC /* ScrollerModel.swift */, @@ -1260,6 +1307,8 @@ D29DF28121E7AB23003B2FB9 /* MVMCoreUICommonViewsUtility.m */, D29DF14D21E693AD003B2FB9 /* MFFonts.h */, D29DF14C21E693AD003B2FB9 /* MFFonts.m */, + 9458C3152406C8FD00930963 /* UIFont+FontWrapping.h */, + 9458C3162406C8FD00930963 /* UIFont+FontWrapping.m */, D29DF29F21E7AF4E003B2FB9 /* MVMCoreUIUtility.h */, D29DF2A021E7AF4E003B2FB9 /* MVMCoreUIUtility.m */, D29DF2A721E7B2F9003B2FB9 /* MVMCoreUIConstants.h */, @@ -1285,12 +1334,11 @@ D29DF16821E69E1F003B2FB9 /* Buttons */ = { isa = PBXGroup; children = ( + 0AE98BAD23FEF92B004C5109 /* Link */, 01F2A03123A4498200D954D8 /* CaretLinkModel.swift */, DBC4391A224421A0001AB423 /* CaretLink.swift */, D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */, D2E2A99E23E07F8A000B42E6 /* PillButton.swift */, - D28A838823CCCFCB00DFE4FC /* LinkModel.swift */, - C07065C32395677300FBF997 /* Link.swift */, D28A838C23CCDCC200DFE4FC /* PrimaryButton+MoleculeProtocolExtension.swift */, D28A837623C79FC600DFE4FC /* MFCustomButton+ActionModel.swift */, ); @@ -1321,6 +1369,7 @@ 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */, 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */, 0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */, + 011D95AE2407266E000E3791 /* RadioButtonModel.swift */, 01004F2F22721C3800991ECC /* RadioButton.swift */, D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */, 943784F3236B77BB006A1E82 /* GraphView.swift */, @@ -1329,6 +1378,8 @@ 0AA33B392398524F0067DD0F /* Toggle.swift */, D260105423CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift */, 012CA99D2385A2D3003F810F /* MFView+ModelExtension.swift */, + 0AE98BB623FF18E9004C5109 /* ArrowModel.swift */, + 0AE98BB423FF18D2004C5109 /* Arrow.swift */, ); path = Views; sourceTree = ""; @@ -1438,10 +1489,11 @@ D29DF31521ECECC0003B2FB9 /* Fonts */ = { isa = PBXGroup; children = ( - D29DF31621ECECC0003B2FB9 /* NHaasGroteskDSStd-45Lt.otf */, + 94CA227A24058533002D6750 /* VerizonNHGeDS-Bold.otf */, + 94CA227924058533002D6750 /* VerizonNHGeDS-Regular.otf */, + 94CA227824058533002D6750 /* VerizonNHGeTX-Bold.otf */, + 94CA227B24058533002D6750 /* VerizonNHGeTX-Regular.otf */, D29DF31721ECECC0003B2FB9 /* OCRAExtended.ttf */, - D29DF31821ECECC0003B2FB9 /* NHaasGroteskDSStd-75Bd.otf */, - D29DF31921ECECC0003B2FB9 /* NHaasGroteskDSStd-55Rg.otf */, ); path = Fonts; sourceTree = ""; @@ -1522,6 +1574,7 @@ D29770F421F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.h in Headers */, D29DF15421E69760003B2FB9 /* MVMCoreUIPanelButtonProtocol.h in Headers */, D2A514582211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.h in Headers */, + 9458C3172406C8FD00930963 /* UIFont+FontWrapping.h in Headers */, D29DF0D121E404D4003B2FB9 /* MVMCoreUI.h in Headers */, D29DF29A21E7ADB8003B2FB9 /* MFProgrammaticTableViewController.h in Headers */, D29DF11521E6805F003B2FB9 /* UIColor+MFConvenience.h in Headers */, @@ -1641,14 +1694,15 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 94CA227F24058534002D6750 /* VerizonNHGeTX-Regular.otf in Resources */, D29DF2AF21E7B3A4003B2FB9 /* MFTextView.xib in Resources */, - D29DF31C21ECECC0003B2FB9 /* NHaasGroteskDSStd-75Bd.otf in Resources */, - D29DF31D21ECECC0003B2FB9 /* NHaasGroteskDSStd-55Rg.otf in Resources */, 0A21DB8E235E06EF00C160A2 /* MFDigitTextField.xib in Resources */, + 94CA227C24058534002D6750 /* VerizonNHGeTX-Bold.otf in Resources */, D29DF32C21EE8736003B2FB9 /* Localizable.strings in Resources */, 0A21DB86235E06EF00C160A2 /* MFTextField.xib in Resources */, - D29DF31A21ECECC0003B2FB9 /* NHaasGroteskDSStd-45Lt.otf in Resources */, + 94CA227D24058534002D6750 /* VerizonNHGeDS-Regular.otf in Resources */, D29DF32E21EE8C3D003B2FB9 /* Media.xcassets in Resources */, + 94CA227E24058534002D6750 /* VerizonNHGeDS-Bold.otf in Resources */, D29DF31B21ECECC0003B2FB9 /* OCRAExtended.ttf in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1678,7 +1732,7 @@ D2FB151D23A40F1500C20E10 /* MoleculeStackItem.swift in Sources */, AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */, D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */, - 0116A4E5228B19640094F3ED /* RadioButtonModel.swift in Sources */, + 0116A4E5228B19640094F3ED /* RadioButtonSelectionHelper.swift in Sources */, 017BEB48236230DB0024EF95 /* MoleculeViewProtocol.swift in Sources */, D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */, D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */, @@ -1698,6 +1752,7 @@ DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */, D224798C231450C8003FCCF9 /* HeadlineBodyToggle.swift in Sources */, 017BEB442362192F0024EF95 /* MVMCoreUIMoleculeMappingObject+ModelExtension.swift in Sources */, + 9458C3182406C8FD00930963 /* UIFont+FontWrapping.m in Sources */, 522679C123FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift in Sources */, 9445890C2385BCE300DE9FD4 /* ProgressBarModel.swift in Sources */, 9445891F2385D2E900DE9FD4 /* CaretViewModel.swift in Sources */, @@ -1727,9 +1782,11 @@ C695A69623C990BC00BFB94E /* DoughnutChart.swift in Sources */, 014AA72D23C5059B006F3E93 /* StackPageTemplateModel.swift in Sources */, D260106123D0C02A00764D80 /* StackItemModelProtocol.swift in Sources */, + 0AE98BAF23FEF956004C5109 /* ExternalLink.swift in Sources */, 012A88C4238D86E600FE3DA1 /* CarouselItemModelProtocol.swift in Sources */, D2E2A9A123E095AB000B42E6 /* ButtonModelProtocol.swift in Sources */, 94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */, + 52B201D324081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift in Sources */, D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */, 014AA73123C5059B006F3E93 /* ListPageTemplateModel.swift in Sources */, 017BEB4023620A230024EF95 /* TextFieldModel.swift in Sources */, @@ -1773,6 +1830,7 @@ D2B18B812360945C00A9AEDC /* View.swift in Sources */, C6FA7D5423C77A4A00A3614A /* NumberedList.swift in Sources */, D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */, + 525019E52406852100EED91C /* ListFourColumnDataUsageDividerModel.swift in Sources */, 0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */, 94FB966323D797DA003D482B /* MFTextButton.m in Sources */, D260105323CEA61600764D80 /* ToggleModel.swift in Sources */, @@ -1801,6 +1859,7 @@ D29DF17A21E69E1F003B2FB9 /* MFCustomButton.m in Sources */, 017BEB7B236763000024EF95 /* LineModel.swift in Sources */, 94C2D9A523872C350006CF46 /* LabelAttributeFontModel.swift in Sources */, + 011D95AF2407266E000E3791 /* RadioButtonModel.swift in Sources */, 017BEB7F23676E870024EF95 /* MoleculeObjectMapping.swift in Sources */, D274CA332236A78900B01B62 /* FooterView.swift in Sources */, D29DF2BF21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.m in Sources */, @@ -1833,11 +1892,14 @@ 0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */, 8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */, D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */, + 525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */, + 0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */, DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */, 0A21DB89235E06EF00C160A2 /* MFMdnTextField.m in Sources */, D224798A2314445E003FCCF9 /* LabelToggle.swift in Sources */, D22D1F47220496A30077CEC0 /* MVMCoreUISwitch.m in Sources */, C695A67F23C9830600BFB94E /* UnOrderedListModel.swift in Sources */, + 0AE98BB523FF18D2004C5109 /* Arrow.swift in Sources */, 017BEB4223620AD20024EF95 /* FormModelProtocol.swift in Sources */, D2D90B442404789000DD6EC9 /* MoleculeContainerProtocol.swift in Sources */, 012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */, @@ -1862,12 +1924,14 @@ 01EB369323609801006832FA /* HeaderModel.swift in Sources */, D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */, 0A21DB83235DFBC500C160A2 /* MdnEntryField.swift in Sources */, + 0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */, D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */, 012A88C6238DA34000FE3DA1 /* ModuleMoleculeModel.swift in Sources */, 94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */, D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */, D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */, 0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */, + 52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */, D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */, 0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */, 94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */, diff --git a/MVMCoreUI/Atoms/Buttons/CaretLink.swift b/MVMCoreUI/Atoms/Buttons/CaretLink.swift index ca665928..50eb7f83 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretLink.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretLink.swift @@ -125,7 +125,7 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { setTitleColor(disabledColor, for: .disabled) } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let caretLinkModel = model as? CaretLinkModel else { return } if let color = caretLinkModel.backgroundColor { backgroundColor = color.uiColor @@ -147,7 +147,7 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { return .leading } - open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 10.5 } } diff --git a/MVMCoreUI/Atoms/Buttons/Link/ExternalLink.swift b/MVMCoreUI/Atoms/Buttons/Link/ExternalLink.swift new file mode 100644 index 00000000..3cd601b6 --- /dev/null +++ b/MVMCoreUI/Atoms/Buttons/Link/ExternalLink.swift @@ -0,0 +1,57 @@ +// +// ExternalLink.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 2/20/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + + +open class ExternalLink: Link { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public var exportImageView: UIImageView? + + //-------------------------------------------------- + // 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? ExternalLinkModel else { return } + + exportImageView?.tintColor = model.textColor.uiColor + } + + //-------------------------------------------------- + // MARK: - MVMCoreViewProtocol + //-------------------------------------------------- + + open override func setupView() { + super.setupView() + + let image = MVMCoreUIUtility.imageNamed("externalLink") + exportImageView = UIImageView(image: image?.withRenderingMode(.alwaysTemplate)) + + guard let exportIcon = exportImageView else { return } + + exportIcon.contentMode = .scaleAspectFit + exportIcon.translatesAutoresizingMaskIntoConstraints = false + + addSubview(exportIcon) + trailingAnchor.constraint(greaterThanOrEqualTo: exportIcon.trailingAnchor).isActive = true + + if let titleLabel = titleLabel { + let dimension = round(0.6 * titleLabel.font.pointSize) + exportIcon.heightAnchor.constraint(equalToConstant: dimension).isActive = true + exportIcon.widthAnchor.constraint(equalToConstant: dimension).isActive = true + exportIcon.leadingAnchor.constraint(equalTo: titleLabel.trailingAnchor, constant: PaddingOne).isActive = true + exportIcon.bottomAnchor.constraint(equalTo: titleLabel.lastBaselineAnchor).isActive = true + } + } +} diff --git a/MVMCoreUI/Atoms/Buttons/Link/ExternalLinkModel.swift b/MVMCoreUI/Atoms/Buttons/Link/ExternalLinkModel.swift new file mode 100644 index 00000000..f492a546 --- /dev/null +++ b/MVMCoreUI/Atoms/Buttons/Link/ExternalLinkModel.swift @@ -0,0 +1,16 @@ +// +// ExternalLinkModel.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 2/20/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +open class ExternalLinkModel: LinkModel { + + override open class var identifier: String { + return "externalLink" + } +} diff --git a/MVMCoreUI/Atoms/Buttons/Link.swift b/MVMCoreUI/Atoms/Buttons/Link/Link.swift similarity index 83% rename from MVMCoreUI/Atoms/Buttons/Link.swift rename to MVMCoreUI/Atoms/Buttons/Link/Link.swift index 5dbbed16..1259d0d8 100644 --- a/MVMCoreUI/Atoms/Buttons/Link.swift +++ b/MVMCoreUI/Atoms/Buttons/Link/Link.swift @@ -40,9 +40,10 @@ import UIKit // MARK: - ModelMoleculeViewProtocol //-------------------------------------------------- - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? LinkModel else { return } + setTitle(model.title, for: .normal) setTitleColor(model.textColor.uiColor, for: .normal) setTitleColor(model.disabledColor.uiColor, for: .disabled) @@ -50,7 +51,7 @@ import UIKit set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) } - open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 31.0 } } @@ -58,7 +59,7 @@ import UIKit // MARK: - MVMCoreViewProtocol extension Link { - public override func updateView(_ size: CGFloat) { + open override func updateView(_ size: CGFloat) { super.updateView(size) DispatchQueue.main.async { [weak self] in guard let self = self else { return } @@ -70,7 +71,7 @@ extension Link { } } - public override func setupView() { + open override func setupView() { super.setupView() backgroundColor = .clear contentMode = .redraw @@ -86,7 +87,7 @@ extension Link { // MARK: - MVMCoreUIViewConstrainingProtocol extension Link: MVMCoreUIViewConstrainingProtocol { - public func horizontalAlignment() -> UIStackView.Alignment { + open func horizontalAlignment() -> UIStackView.Alignment { return .leading } } diff --git a/MVMCoreUI/Atoms/Buttons/LinkModel.swift b/MVMCoreUI/Atoms/Buttons/Link/LinkModel.swift similarity index 95% rename from MVMCoreUI/Atoms/Buttons/LinkModel.swift rename to MVMCoreUI/Atoms/Buttons/Link/LinkModel.swift index 7094a038..6e7fc83d 100644 --- a/MVMCoreUI/Atoms/Buttons/LinkModel.swift +++ b/MVMCoreUI/Atoms/Buttons/Link/LinkModel.swift @@ -8,12 +8,14 @@ import UIKit -public class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { +open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - public static var identifier: String = "link" + public class var identifier: String { + return "link" + } public var backgroundColor: Color? public var title: String diff --git a/MVMCoreUI/Atoms/Buttons/MFCustomButton+ActionModel.swift b/MVMCoreUI/Atoms/Buttons/MFCustomButton+ActionModel.swift index d008a7fb..84f4be33 100644 --- a/MVMCoreUI/Atoms/Buttons/MFCustomButton+ActionModel.swift +++ b/MVMCoreUI/Atoms/Buttons/MFCustomButton+ActionModel.swift @@ -9,7 +9,9 @@ import Foundation public extension MFCustomButton { + func set(with action: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + buttonDelegate = delegateObject?.buttonDelegate add({ [weak self] sender in guard let self = self else { return } diff --git a/MVMCoreUI/Atoms/Buttons/PillButton.swift b/MVMCoreUI/Atoms/Buttons/PillButton.swift index d3d09cee..d7fa8db5 100644 --- a/MVMCoreUI/Atoms/Buttons/PillButton.swift +++ b/MVMCoreUI/Atoms/Buttons/PillButton.swift @@ -119,9 +119,9 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation } // MARK: - ModelMoleculeViewProtocol - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { // The button will get styled in the enable check in super. - super.setWithModel(model, delegateObject, additionalData) + super.set(with: model, delegateObject, additionalData) guard let model = model as? ButtonModel else { return } setTitle(model.title, for: .normal) @@ -132,8 +132,8 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation } } - open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - PillButton.getHeight(for: (molecule as? ButtonModel)?.size, size: MVMCoreUIUtility.getWidth()) + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + PillButton.getHeight(for: (model as? ButtonModel)?.size, size: MVMCoreUIUtility.getWidth()) } // MARK: - MVMCoreViewProtocol diff --git a/MVMCoreUI/Atoms/Buttons/PrimaryButton+MoleculeProtocolExtension.swift b/MVMCoreUI/Atoms/Buttons/PrimaryButton+MoleculeProtocolExtension.swift index 39b015ae..0e2368b8 100644 --- a/MVMCoreUI/Atoms/Buttons/PrimaryButton+MoleculeProtocolExtension.swift +++ b/MVMCoreUI/Atoms/Buttons/PrimaryButton+MoleculeProtocolExtension.swift @@ -10,8 +10,9 @@ import Foundation // temporary until link is finished extension PrimaryButton: ModelMoleculeViewProtocol { - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { guard let model = model as? ButtonModel else { return } + setTitle(model.title, for: .normal) backgroundColor = model.backgroundColor?.uiColor @@ -23,7 +24,6 @@ extension PrimaryButton: ModelMoleculeViewProtocol { FormValidator.setupValidation(molecule: selfForm, delegate: delegateObject?.formValidationProtocol) } - if let style = model.style { switch style { case .primary: @@ -32,6 +32,7 @@ extension PrimaryButton: ModelMoleculeViewProtocol { setAsSecondaryCustom() } } + if let size = model.size { switch size { case .standard: diff --git a/MVMCoreUI/Atoms/TextFields/BaseDropdownEntryField.swift b/MVMCoreUI/Atoms/TextFields/BaseDropdownEntryField.swift index 70b46866..b7c59fd5 100644 --- a/MVMCoreUI/Atoms/TextFields/BaseDropdownEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/BaseDropdownEntryField.swift @@ -69,12 +69,12 @@ import UIKit dropDownCaretView.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? BaseDropdownEntryFieldModel else { return } - dropDownCaretView.setWithModel(model.caretView, delegateObject, additionalData) + dropDownCaretView.setOptional(with: model.caretView, delegateObject, additionalData) } } diff --git a/MVMCoreUI/Atoms/TextFields/DateDropdownEntryField.swift b/MVMCoreUI/Atoms/TextFields/DateDropdownEntryField.swift index acfe0a42..95174096 100644 --- a/MVMCoreUI/Atoms/TextFields/DateDropdownEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/DateDropdownEntryField.swift @@ -111,8 +111,8 @@ import UIKit setTextWith(date: datePicker?.date) } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? DateDropdownEntryFieldModel else { return } diff --git a/MVMCoreUI/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atoms/TextFields/DigitEntryField.swift index 9febf0c1..53181bff 100644 --- a/MVMCoreUI/Atoms/TextFields/DigitEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/DigitEntryField.swift @@ -328,7 +328,7 @@ import UIKit } } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let model = model as? DigitEntryFieldModel else { return } @@ -341,7 +341,7 @@ import UIKit MVMCoreUICommonViewsUtility.addDismissToolbar(digitBox.digitField, delegate: delegateObject as? UITextFieldDelegate) } - super.setWithModel(model, delegateObject, additionalData) + super.set(with: model, delegateObject, additionalData) } } diff --git a/MVMCoreUI/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atoms/TextFields/EntryField.swift index 82cc69f6..bbea1c62 100644 --- a/MVMCoreUI/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/EntryField.swift @@ -240,13 +240,13 @@ import UIKit entryFieldContainer.reset() } - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) self.delegateObject = delegateObject guard let model = model as? EntryFieldModel else { return } - entryFieldContainer.setWithModel(model, delegateObject, additionalData) + entryFieldContainer.set(with: model, delegateObject, additionalData) title = model.title feedback = model.feedback diff --git a/MVMCoreUI/Atoms/TextFields/ItemDropdownEntryField.swift b/MVMCoreUI/Atoms/TextFields/ItemDropdownEntryField.swift index 48728ce9..0ecfc4ad 100644 --- a/MVMCoreUI/Atoms/TextFields/ItemDropdownEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/ItemDropdownEntryField.swift @@ -95,8 +95,8 @@ open class ItemDropdownEntryField: BaseDropdownEntryField { } } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? ItemDropdownEntryFieldModel else { return } diff --git a/MVMCoreUI/Atoms/TextFields/MFTextField+ModelExtension.swift b/MVMCoreUI/Atoms/TextFields/MFTextField+ModelExtension.swift index a077c285..e57cec9c 100644 --- a/MVMCoreUI/Atoms/TextFields/MFTextField+ModelExtension.swift +++ b/MVMCoreUI/Atoms/TextFields/MFTextField+ModelExtension.swift @@ -16,7 +16,7 @@ enum TextType: String { } extension MFTextField: ModelMoleculeViewProtocol { // - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { //TODO: Need to create setWithModel in ViewConstraining View #warning("This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView.") //TODO: This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView. diff --git a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift index 67721f27..61f6c82c 100644 --- a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift @@ -277,8 +277,8 @@ import UIKit resignFirstResponder() } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? TextEntryFieldModel else { return } diff --git a/MVMCoreUI/Atoms/Views/Arrow.swift b/MVMCoreUI/Atoms/Views/Arrow.swift new file mode 100644 index 00000000..e932dd60 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/Arrow.swift @@ -0,0 +1,100 @@ +// +// Arrow.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 2/20/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +open class Arrow: View { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + var arrowLayer = CAShapeLayer() + + public var arrowModel: ArrowModel? { + return model as? ArrowModel + } + + //-------------------------------------------------- + // MARK: - Constraints + //-------------------------------------------------- + + public var heightConstraint: NSLayoutConstraint? + public var widthConstraint: NSLayoutConstraint? + + public func pinHeightAndWidth(constant: CGFloat = 12) { + + heightConstraint = heightAnchor.constraint(equalToConstant: constant) + widthConstraint = widthAnchor.constraint(equalToConstant: constant) + heightConstraint?.isActive = true + widthConstraint?.isActive = true + } + + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + + open override func setupView() { + super.setupView() + + drawShapeLayer() + isOpaque = false + layer.addSublayer(arrowLayer) + arrowLayer.strokeEnd = 1 + } + + //-------------------------------------------------- + // MARK: - Drawing + //-------------------------------------------------- + + open override func draw(_ rect: CGRect) { + super.draw(rect) + + arrowLayer.transform = CATransform3DIdentity + drawShapeLayer() + + if let degrees = arrowModel?.degrees { + let radians = CGFloat(degrees * Float.pi / 180) + arrowLayer.transform = CATransform3DMakeRotation(-radians, 0.0, 0.0, 1.0) + } + } + + private func drawShapeLayer() { + + arrowLayer.frame = bounds + arrowLayer.strokeColor = arrowModel?.color.cgColor + arrowLayer.fillColor = UIColor.clear.cgColor + arrowLayer.path = arrowPath() + arrowLayer.lineJoin = .miter + arrowLayer.lineCap = .butt + arrowLayer.lineWidth = arrowModel?.lineWidth ?? 1 + } + + private func arrowPath() -> CGPath { + + let length = max(bounds.size.height, bounds.size.width) + let inset = (arrowModel?.lineWidth ?? 1) / 2 + let midLength = length / 2 + + var startPoint = CGPoint(x: midLength, y: inset) + let pivotPoint = CGPoint(x: length - inset, y: midLength) + var endPoint = CGPoint(x: midLength, y: length - inset) + + let bezierPath = UIBezierPath() + bezierPath.move(to: startPoint) + bezierPath.addLine(to: pivotPoint) + bezierPath.addLine(to: endPoint) + + startPoint = CGPoint(x: inset, y: midLength) + endPoint = CGPoint(x: length - inset, y: midLength) + + bezierPath.move(to: startPoint) + bezierPath.addLine(to: pivotPoint) + + return bezierPath.cgPath + } +} diff --git a/MVMCoreUI/Atoms/Views/ArrowModel.swift b/MVMCoreUI/Atoms/Views/ArrowModel.swift new file mode 100644 index 00000000..2547f8d1 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/ArrowModel.swift @@ -0,0 +1,80 @@ +// +// ArrowModel.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 2/20/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +open class ArrowModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public static var identifier: String = "arrow" + public var backgroundColor: Color? + + public var color: Color = Color(uiColor: .mvmBlack) + public var degrees: Float = 0 + public var lineWidth: CGFloat = 1 + + public var height: CGFloat = 12 + public var width: CGFloat = 12 + + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + + private enum CodingKeys: String, CodingKey { + case moleculeName + case backgroundColor + case color + case degrees + case size + case lineWidth + case height + case width + } + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) { + self.color = color + } + + if let degrees = try typeContainer.decodeIfPresent(Float.self, forKey: .degrees) { + self.degrees = degrees + } + + if let lineWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .lineWidth) { + self.lineWidth = lineWidth + } + + if let height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) { + self.lineWidth = height + } + + if let width = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .width) { + self.width = width + } + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encode(color, forKey: .color) + try container.encode(degrees, forKey: .degrees) + try container.encodeIfPresent(backgroundColor, forKey: .lineWidth) + try container.encode(width, forKey: .width) + try container.encode(height, forKey: .height) + } +} diff --git a/MVMCoreUI/Atoms/Views/CaretView.swift b/MVMCoreUI/Atoms/Views/CaretView.swift index 26573af5..fff56f82 100644 --- a/MVMCoreUI/Atoms/Views/CaretView.swift +++ b/MVMCoreUI/Atoms/Views/CaretView.swift @@ -184,12 +184,12 @@ open class CaretView: View { public override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { guard let json = json, let model = try? Self.decodeJSONToModel(json: json, type: CaretViewModel.self) else { return } - setWithModel(model, delegateObject, additionalData) + set(with: model, delegateObject, additionalData) } //MARK: - MVMCoreMoleculeViewProtocol - override public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + override public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let caretModel = model as? CaretViewModel else { return } diff --git a/MVMCoreUI/Atoms/Views/Checkbox.swift b/MVMCoreUI/Atoms/Views/Checkbox.swift index 27bed31e..fd186d7e 100644 --- a/MVMCoreUI/Atoms/Views/Checkbox.swift +++ b/MVMCoreUI/Atoms/Views/Checkbox.swift @@ -395,7 +395,7 @@ import MVMCore heightConstraint?.constant = dimension } - layoutIfNeeded() + //layoutIfNeeded() } public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { @@ -456,8 +456,8 @@ import MVMCore } } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? CheckboxModel else { return } diff --git a/MVMCoreUI/Atoms/Views/CheckboxLabel.swift b/MVMCoreUI/Atoms/Views/CheckboxLabel.swift index 700cbd4f..72429aa2 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxLabel.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxLabel.swift @@ -115,15 +115,15 @@ } } - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let checkBoxWithLabelModel = model as? CheckboxLabelModel else { return } if let checkboxAlignment = checkBoxWithLabelModel.checkboxAlignment { alignCheckbox(checkboxAlignment) } - checkbox.setWithModel(checkBoxWithLabelModel.checkbox, delegateObject, additionalData) - label.setWithModel(checkBoxWithLabelModel.label, delegateObject, additionalData) + checkbox.set(with: checkBoxWithLabelModel.checkbox, delegateObject, additionalData) + label.set(with: checkBoxWithLabelModel.label, delegateObject, additionalData) } } diff --git a/MVMCoreUI/Atoms/Views/DashLine.swift b/MVMCoreUI/Atoms/Views/DashLine.swift index fc8f8bc3..63b28dbd 100644 --- a/MVMCoreUI/Atoms/Views/DashLine.swift +++ b/MVMCoreUI/Atoms/Views/DashLine.swift @@ -89,12 +89,12 @@ open class DashLine: View { open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { guard let json = json, let model = try? Self.decodeJSONToModel(json: json, type: DashLineModel.self) else { return } - setWithModel(model, delegateObject, additionalData) + set(with: model, delegateObject, additionalData) } //MARK: - MVMCoreMoleculeViewProtocol - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let dashLineModel = dashModel else { return } diff --git a/MVMCoreUI/Atoms/Views/GraphView.swift b/MVMCoreUI/Atoms/Views/GraphView.swift index 12f2fca8..997c58d0 100644 --- a/MVMCoreUI/Atoms/Views/GraphView.swift +++ b/MVMCoreUI/Atoms/Views/GraphView.swift @@ -26,8 +26,8 @@ import UIKit widthAnchor.constraint(equalTo: heightAnchor).isActive = true } - override open func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? CircleProgressModel else { return } createGraphCircle(model) rotationAnimation(model) @@ -35,7 +35,7 @@ import UIKit override open func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { guard let json = json, let model = try? Self.decodeJSONToModel(json: json, type: CircleProgressModel.self) else { return } - setWithModel(model, delegateObject, additionalData) + set(with: model, delegateObject, additionalData) } class func getAngle(_ piValue: Double) -> Double { diff --git a/MVMCoreUI/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atoms/Views/Label/Label.swift index f08d532d..c7e72204 100644 --- a/MVMCoreUI/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label/Label.swift @@ -132,6 +132,89 @@ public typealias ActionBlock = () -> () // MARK: - Factory Functions //------------------------------------------------------ + /// Title 2XLarge + @objc public static func createLabelTitle2XLarge(_ scale: Bool) -> Label { + let label = Label.label() + label.styleTitle2XLarge(scale) + return label + } + + /// TitleXLarge + @objc public static func createLabelTitleXLarge(_ scale: Bool) -> Label { + let label = Label.label() + label.styleTitleXLarge(scale) + return label + } + + /// BoldTitleLarge + @objc public static func createLabelBoldTitleLarge(_ scale: Bool) -> Label { + let label = Label.label() + label.styleBoldTitleLarge(scale) + return label + } + + /// RegularTitleLarge + @objc public static func createLabelRegularTitleLarge(_ scale: Bool) -> Label { + let label = Label.label() + label.styleRegularTitleLarge(scale) + return label + } + + /// BoldTitleMedium + @objc public static func createLabelBoldTitleMedium(_ scale: Bool) -> Label { + let label = Label.label() + label.styleBoldTitleMedium(scale) + return label + } + + /// RegularTitleMedium + @objc public static func createLabelRegularTitleMedium(_ scale: Bool) -> Label { + let label = Label.label() + label.styleRegularTitleMedium(scale) + return label + } + + /// BoldBodyLarge + @objc public static func createLabelBoldBodyLarge(_ scale: Bool) -> Label { + let label = Label.label() + label.styleBoldBodyLarge(scale) + return label + } + + /// RegularBodyLarge + @objc public static func createLabelRegularBodyLarge(_ scale: Bool) -> Label { + let label = Label.label() + label.styleRegularBodyLarge(scale) + return label + } + + /// BoldBodySmall + @objc public static func createLabelBoldBodySmall(_ scale: Bool) -> Label { + let label = Label.label() + label.styleBoldBodySmall(scale) + return label + } + + /// RegularBodySmall + @objc public static func createLabelRegularBodySmall(_ scale: Bool) -> Label { + let label = Label.label() + label.styleRegularBodySmall(scale) + return label + } + /// BoldMicro + @objc public static func createLabelBoldMicro(_ scale: Bool) -> Label { + let label = Label.label() + label.styleBoldMicro(scale) + return label + } + /// RegularMicro + @objc public static func createLabelRegularMicro(_ scale: Bool) -> Label { + let label = Label.label() + label.styleRegularMicro(scale) + return label + } + + //2.0 fonts init methods /// H1 -> HeadlineLarge @objc public static func commonLabelH1(_ scale: Bool) -> Label { let label = Label.label() @@ -219,7 +302,7 @@ public typealias ActionBlock = () -> () case left } - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { clauses = [] @@ -267,16 +350,16 @@ public typealias ActionBlock = () -> () if let fontName = labelModel.fontName { font = MFFonts.mfFont(withName: fontName, size: fontSize ?? standardFontSize) } else if let fontSize = fontSize { - font = font.withSize(fontSize) + font = font.updateSize(fontSize) } } - if let textColorHex = labelModel.textColor, !textColorHex.isEmpty { - textColor = UIColor.mfGet(forHex: textColorHex) + if let color = labelModel.textColor { + textColor = color.uiColor } if let attributes = labelModel.attributes, let labelText = text { - let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: font.withSize(standardFontSize), NSAttributedString.Key.foregroundColor: textColor as UIColor]) + let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: font.updateSize(standardFontSize), NSAttributedString.Key.foregroundColor: textColor as UIColor]) for attribute in attributes { let range = NSRange(location: attribute.location, length: attribute.length) @@ -324,7 +407,7 @@ public typealias ActionBlock = () -> () if let fontName = fontAtt.name { font = MFFonts.mfFont(withName: fontName, size: fontSize ?? self.font.pointSize) } else if let fontSize = fontSize { - font = self.font.withSize(fontSize) + font = self.font.updateSize(fontSize) } if let font = font { attributedString.removeAttribute(.font, range: range) @@ -390,7 +473,7 @@ public typealias ActionBlock = () -> () if let fontName = json?.optionalStringForKey("fontName") { label.font = MFFonts.mfFont(withName: fontName, size: fontSize ?? mvmLabel?.standardFontSize ?? label.font.pointSize) } else if let fontSize = fontSize { - label.font = label.font.withSize(fontSize) + label.font = label.font.updateSize(fontSize) } } @@ -400,7 +483,7 @@ public typealias ActionBlock = () -> () if let attributes = json?.optionalArrayForKey("attributes"), let labelText = label.text { let attributedString = NSMutableAttributedString(string: labelText, - attributes: [NSAttributedString.Key.font: mvmLabel?.font.withSize(mvmLabel!.standardFontSize) ?? label.font as UIFont, + attributes: [NSAttributedString.Key.font: mvmLabel?.font.updateSize(mvmLabel!.standardFontSize) ?? label.font as UIFont, NSAttributedString.Key.foregroundColor: label.textColor as UIColor]) for case let attribute as [String: Any] in attributes { guard let attributeType = attribute.optionalStringForKey(KeyType), @@ -452,7 +535,7 @@ public typealias ActionBlock = () -> () if let fontName = attribute.optionalStringForKey("name") { font = MFFonts.mfFont(withName: fontName, size: fontSize ?? mvmLabel?.standardFontSize ?? label.font.pointSize) } else if let fontSize = fontSize { - font = label.font.withSize(fontSize) + font = label.font.updateSize(fontSize) } if let font = font { @@ -481,6 +564,68 @@ public typealias ActionBlock = () -> () // MARK: - Methods //------------------------------------------------------ + //mva 3.0 font + @objc public func styleTitle2XLarge(_ scale: Bool) { + MFStyler.styleLabelTitle2XLarge(self, genericScaling: false) + setScale(scale) + } + + @objc public func styleTitleXLarge(_ scale: Bool) { + MFStyler.styleLabelTitleXLarge(self, genericScaling: false) + setScale(scale) + } + + @objc public func styleBoldTitleLarge(_ scale: Bool) { + MFStyler.styleLabelBoldTitleLarge(self, genericScaling: false) + setScale(scale) + } + + @objc public func styleRegularTitleLarge(_ scale: Bool) { + MFStyler.styleLabelRegularTitleLarge(self, genericScaling: false) + setScale(scale) + } + + @objc public func styleBoldTitleMedium(_ scale: Bool) { + MFStyler.styleLabelBoldTitleMedium(self, genericScaling: false) + setScale(scale) + } + + @objc public func styleRegularTitleMedium(_ scale: Bool) { + MFStyler.styleLabelRegularTitleMedium(self, genericScaling: false) + setScale(scale) + } + + @objc public func styleBoldBodyLarge(_ scale: Bool) { + MFStyler.styleLabelBoldBodyLarge(self, genericScaling: false) + setScale(scale) + } + + @objc public func styleRegularBodyLarge(_ scale: Bool) { + MFStyler.styleLabelRegularBodyLarge(self, genericScaling: false) + setScale(scale) + } + + @objc public func styleBoldBodySmall(_ scale: Bool) { + MFStyler.styleLabelBoldBodySmall(self, genericScaling: false) + setScale(scale) + } + + @objc public func styleRegularBodySmall(_ scale: Bool) { + MFStyler.styleLabelRegularBodySmall(self, genericScaling: false) + setScale(scale) + } + + @objc public func styleBoldMicro(_ scale: Bool) { + MFStyler.styleLabelBoldMicro(self, genericScaling: false) + setScale(scale) + } + + @objc public func styleRegularMicro(_ scale: Bool) { + MFStyler.styleLabelRegularMicro(self, genericScaling: false) + setScale(scale) + } + + //2.0 fonts @objc public func styleH1(_ scale: Bool) { MFStyler.styleLabelH1(self, genericScaling: false) setScale(scale) @@ -532,7 +677,7 @@ public typealias ActionBlock = () -> () originalAttributedString.enumerateAttribute(.font, in: NSRange(location: 0, length: originalAttributedString.length), options: []) { value, range, stop in if let fontObj = value as? UIFont, let stylerSize = MFStyler.sizeObjectGeneric(forCurrentDevice: fontObj.pointSize)?.getValueBased(onSize: size) { - attributedString.addAttribute(.font, value: fontObj.withSize(stylerSize) as Any, range: range) + attributedString.addAttribute(.font, value: fontObj.updateSize(stylerSize) as Any, range: range) } } @@ -548,7 +693,7 @@ public typealias ActionBlock = () -> () attributedText = attributedString } else if !MVMCoreGetterUtility.fequal(a: Float(standardFontSize), b: 0.0), let sizeObject = sizeObject ?? MFStyler.sizeObjectGeneric(forCurrentDevice: standardFontSize) { - font = font.withSize(sizeObject.getValueBased(onSize: size)) + font = font.updateSize(sizeObject.getValueBased(onSize: size)) } } diff --git a/MVMCoreUI/Atoms/Views/Label/LabelAttributeModel.swift b/MVMCoreUI/Atoms/Views/Label/LabelAttributeModel.swift index 437ec0cc..ddc468b7 100644 --- a/MVMCoreUI/Atoms/Views/Label/LabelAttributeModel.swift +++ b/MVMCoreUI/Atoms/Views/Label/LabelAttributeModel.swift @@ -8,7 +8,7 @@ import Foundation -@objcMembers open class LabelAttributeModel: Model { +@objcMembers open class LabelAttributeModel: ModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atoms/Views/Label/LabelModel.swift b/MVMCoreUI/Atoms/Views/Label/LabelModel.swift index cb9cc0a9..3b5f2b66 100644 --- a/MVMCoreUI/Atoms/Views/Label/LabelModel.swift +++ b/MVMCoreUI/Atoms/Views/Label/LabelModel.swift @@ -18,7 +18,7 @@ import Foundation public var backgroundColor: Color? public var text: String public var accessibilityText: String? - public var textColor: String? + public var textColor: Color? public var fontStyle: String? public var fontName: String? public var fontSize: CGFloat? @@ -68,7 +68,7 @@ import Foundation let typeContainer = try decoder.container(keyedBy: CodingKeys.self) text = try typeContainer.decode(String.self, forKey: .text) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) - textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor) + textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) fontStyle = try typeContainer.decodeIfPresent(String.self, forKey: .fontStyle) fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName) diff --git a/MVMCoreUI/Atoms/Views/LeftRightLabelView.swift b/MVMCoreUI/Atoms/Views/LeftRightLabelView.swift index 1096df37..d8cebb51 100644 --- a/MVMCoreUI/Atoms/Views/LeftRightLabelView.swift +++ b/MVMCoreUI/Atoms/Views/LeftRightLabelView.swift @@ -179,13 +179,14 @@ import Foundation //MARK: - MVMCoreMoleculeViewProtocol - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let leftRightLabelModel = model as? LeftRightLabelModel else { return } - leftTextLabel.setWithModel(leftRightLabelModel.leftText, delegateObject, additionalData) - rightTextLabel.setWithModel(leftRightLabelModel.rightText, delegateObject, additionalData) + leftTextLabel.set(with: leftRightLabelModel.leftText, delegateObject, additionalData) + rightTextLabel.setOptional(with: leftRightLabelModel.rightText, delegateObject, additionalData) + if !leftTextLabel.hasText { constrainRightLabel() } else if !rightTextLabel.hasText { diff --git a/MVMCoreUI/Atoms/Views/Line.swift b/MVMCoreUI/Atoms/Views/Line.swift index d6ec5d8a..37bf5688 100644 --- a/MVMCoreUI/Atoms/Views/Line.swift +++ b/MVMCoreUI/Atoms/Views/Line.swift @@ -67,11 +67,11 @@ import UIKit super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) } - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { if let lineModel = model as? LineModel { setStyle(lineModel.type ?? .standard) } - super.setWithModel(model, delegateObject, additionalData) + super.set(with: model, delegateObject, additionalData) } open override func reset() { diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift index 0079d1a6..e61a5af3 100644 --- a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift @@ -209,7 +209,7 @@ import UIKit } } - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { self.delegateObject = delegateObject // TODO: Temporary, should be moved to init once we have type erasure ready. setAsMolecule() diff --git a/MVMCoreUI/Atoms/Views/MFView+ModelExtension.swift b/MVMCoreUI/Atoms/Views/MFView+ModelExtension.swift index d532d7c4..af14bc44 100644 --- a/MVMCoreUI/Atoms/Views/MFView+ModelExtension.swift +++ b/MVMCoreUI/Atoms/Views/MFView+ModelExtension.swift @@ -9,16 +9,16 @@ import Foundation extension MFView { - public func setUpDefaultWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public func setUpDefaultWithModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { self.model = model - if let backgroundColor = model?.backgroundColor { + if let backgroundColor = model.backgroundColor { self.backgroundColor = backgroundColor.uiColor } } } extension ModelMoleculeViewProtocol where Self: MFView { - func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { setUpDefaultWithModel(model, delegateObject, additionalData) } } diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUISwitch+Model.swift b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch+Model.swift index e2ef7b31..aeccf2ff 100644 --- a/MVMCoreUI/Atoms/Views/MVMCoreUISwitch+Model.swift +++ b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch+Model.swift @@ -10,7 +10,7 @@ import Foundation // temporary until link is finished extension MVMCoreUISwitch: ModelMoleculeViewProtocol { - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { guard let model = model as? ToggleModel else { return } if let castSelf = self as? FormValidationProtocol { diff --git a/MVMCoreUI/Atoms/Views/MultiProgress.swift b/MVMCoreUI/Atoms/Views/MultiProgress.swift index cd05ed0b..02be560c 100644 --- a/MVMCoreUI/Atoms/Views/MultiProgress.swift +++ b/MVMCoreUI/Atoms/Views/MultiProgress.swift @@ -64,8 +64,8 @@ import UIKit } //MARK: - MVMCoreMoleculeViewProtocol - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let multiProgressModel = multiProgressModel else { return } @@ -83,6 +83,6 @@ import UIKit public override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { guard let json = json, let model = try? Self.decodeJSONToModel(json: json, type: MultiProgressBarModel.self) else { return } - setWithModel(model, delegateObject, additionalData) + set(with: model, delegateObject, additionalData) } } diff --git a/MVMCoreUI/Atoms/Views/ProgressBar.swift b/MVMCoreUI/Atoms/Views/ProgressBar.swift index 17d35c29..3f302135 100644 --- a/MVMCoreUI/Atoms/Views/ProgressBar.swift +++ b/MVMCoreUI/Atoms/Views/ProgressBar.swift @@ -51,7 +51,7 @@ import Foundation } //MARK: - MVMCoreMoleculeViewProtocol - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let progressBarModel = model as? ProgressBarModel else { return } @@ -66,7 +66,7 @@ import Foundation // MARK: - MVMCoreUIMoleculeViewProtocol public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { guard let json = json, let model = try? Self.decodeJSONToModel(json: json, type: ProgressBarModel.self) else { return } - setWithModel(model, delegateObject, additionalData) + set(with: model, delegateObject, additionalData) } public func reset() { diff --git a/MVMCoreUI/Atoms/Views/RadioButton.swift b/MVMCoreUI/Atoms/Views/RadioButton.swift index 23588a4c..47eeb0ca 100644 --- a/MVMCoreUI/Atoms/Views/RadioButton.swift +++ b/MVMCoreUI/Atoms/Views/RadioButton.swift @@ -32,7 +32,7 @@ import UIKit return json?.optionalStringForKey("radioGroupName") ?? json?.optionalStringForKey("fieldKey") }() - lazy var radioButtonModel: RadioButtonModel? = { + lazy var radioButtonModel: RadioButtonSelectionHelper? = { [unowned self] in if let radioGroupName = radioGroupName, let radioButtonModel = delegateObject?.formValidationProtocol?.formValidatorModel?()?.radioButtonsModelByGroup[radioGroupName] { @@ -98,6 +98,14 @@ import UIKit accessibilityTraits = .button accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "radio_action_hint") } + + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? RadioButtonModel else { + return + } + setWithJSON(model.toJSON(), delegateObject: delegateObject, additionalData: additionalData) + } } // MARK: - MVMCoreUIViewConstrainingProtocol @@ -123,11 +131,11 @@ extension RadioButton { isRequired = jsonDictionary.boolForKey("required") self.delegateObject = delegateObject - let radioButtonModel = RadioButtonModel.setupForRadioButtonGroup(radioButton: self, + let radioButtonModel = RadioButtonSelectionHelper.setupForRadioButtonGroup(radioButton: self, formValidator: delegateObject?.formValidationProtocol?.formValidatorModel?()) FormValidator.setupValidation(molecule: radioButtonModel, delegate: delegateObject?.formValidationProtocol) } - + public override func reset() { super.reset() backgroundColor = .white diff --git a/MVMCoreUI/Atoms/Views/RadioButtonModel.swift b/MVMCoreUI/Atoms/Views/RadioButtonModel.swift new file mode 100644 index 00000000..c8443691 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/RadioButtonModel.swift @@ -0,0 +1,17 @@ +// +// RadioButtonModel.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 2/26/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + + +public class RadioButtonModel: MoleculeModelProtocol { + public static var identifier: String = "radioButton" + public var backgroundColor: Color? + public var state: Bool = false + public var fieldKey: String? +} diff --git a/MVMCoreUI/Atoms/Views/Toggle.swift b/MVMCoreUI/Atoms/Views/Toggle.swift index 80425054..ee888b3f 100644 --- a/MVMCoreUI/Atoms/Views/Toggle.swift +++ b/MVMCoreUI/Atoms/Views/Toggle.swift @@ -334,7 +334,7 @@ public typealias ActionBlockConfirmation = () -> (Bool) } // MARK:- ModelMoleculeViewProtocol - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let toggleModel = model as? ToggleModel else { return } @@ -343,7 +343,7 @@ public typealias ActionBlockConfirmation = () -> (Bool) setWithJSON(toggleModelJSON, delegateObject: delegateObject, additionalData: additionalData) } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return Self.getContainerHeight() } } diff --git a/MVMCoreUI/BaseClasses/Button.swift b/MVMCoreUI/BaseClasses/Button.swift index c0ff0e81..8722b800 100644 --- a/MVMCoreUI/BaseClasses/Button.swift +++ b/MVMCoreUI/BaseClasses/Button.swift @@ -87,10 +87,10 @@ public typealias ButtonAction = (Button) -> () } // MARK:- ModelMoleculeViewProtocol - open func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { self.model = model - if let backgroundColor = model?.backgroundColor { + if let backgroundColor = model.backgroundColor { self.backgroundColor = backgroundColor.uiColor } @@ -100,15 +100,15 @@ public typealias ButtonAction = (Button) -> () set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) } - open class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { - return model?.moleculeName + open class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { + return model.moleculeName } - open class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return nil } - open class func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { + open class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { return nil } } diff --git a/MVMCoreUI/BaseClasses/Control.swift b/MVMCoreUI/BaseClasses/Control.swift index d73e0fef..265e56b3 100644 --- a/MVMCoreUI/BaseClasses/Control.swift +++ b/MVMCoreUI/BaseClasses/Control.swift @@ -48,22 +48,22 @@ import UIKit } // MARK:- ModelMoleculeViewProtocol - open func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { self.model = model - if let backgroundColor = model?.backgroundColor { + if let backgroundColor = model.backgroundColor { self.backgroundColor = backgroundColor.uiColor } } - open class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { - return model?.moleculeName + open class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { + return model.moleculeName } - open class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return nil } - open class func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { + open class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { return nil } } diff --git a/MVMCoreUI/BaseClasses/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift index d96a4587..3154bbb9 100644 --- a/MVMCoreUI/BaseClasses/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -96,8 +96,8 @@ import UIKit super.layoutSubviews() // Ensures accessory view aligns to the center y derived from the - if let center = heroAccessoryCenter { - accessoryView?.center.y = center.y + if let _ = heroAccessoryCenter { + alignAccessoryToHero() } } @@ -150,8 +150,8 @@ import UIKit contentView.preservesSuperviewLayoutMargins = false } - //TODO: Model, Change to model - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + //TODO: ModelProtocol, Change to model + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let model = model as? ListItemModelProtocol else { return } self.listItemModel = model @@ -169,7 +169,7 @@ import UIKit // override the separator if let separator = model.line { addSeparatorsIfNeeded() - bottomSeparatorView?.setWithModel(separator, nil, nil) + bottomSeparatorView?.set(with: separator, nil, nil) } if let moleculeModel = model as? MoleculeModelProtocol, @@ -183,11 +183,11 @@ import UIKit backgroundColor = .white } - public class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { - return model?.moleculeName + public class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { + return model.moleculeName } - public class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return nil } @@ -246,8 +246,8 @@ import UIKit public func setLines(with model: LineModel?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?, indexPath: IndexPath) { addSeparatorsIfNeeded() if let model = model { - topSeparatorView?.setWithModel(model, delegateObject, additionalData) - bottomSeparatorView?.setWithModel(model, delegateObject, additionalData) + topSeparatorView?.set(with: model, delegateObject, additionalData) + bottomSeparatorView?.set(with: model, delegateObject, additionalData) } else { topSeparatorView?.setStyle(.standard) bottomSeparatorView?.setStyle(.standard) diff --git a/MVMCoreUI/BaseClasses/View.swift b/MVMCoreUI/BaseClasses/View.swift index a117d60a..860ce442 100644 --- a/MVMCoreUI/BaseClasses/View.swift +++ b/MVMCoreUI/BaseClasses/View.swift @@ -40,22 +40,22 @@ import UIKit } // MARK:- ModelMoleculeViewProtocol - open func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { self.model = model - if let backgroundColor = model?.backgroundColor { + if let backgroundColor = model.backgroundColor { self.backgroundColor = backgroundColor.uiColor } } - open class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { - return model?.moleculeName + open class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { + return model.moleculeName } - open class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return nil } - open class func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { + open class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { return nil } } diff --git a/MVMCoreUI/Categories/NSLayoutConstraintExtension.swift b/MVMCoreUI/Categories/NSLayoutConstraintExtension.swift index 4057a88c..242e3fc0 100644 --- a/MVMCoreUI/Categories/NSLayoutConstraintExtension.swift +++ b/MVMCoreUI/Categories/NSLayoutConstraintExtension.swift @@ -10,48 +10,48 @@ import Foundation public extension NSLayoutConstraint { - /// Pins the views vertically in the super view, allowing the super to expand depending on the tallest view. Shorter views are aligned center. - static func pinViewsVerticalExpandableAlignCenter(_ views: [UIView]) { + /// Pins the views vertically to the top and bottom anchor, allowing the super to expand depending on the tallest view. Shorter views are aligned center. + static func pinViewsVerticalExpandableAlignCenter(_ views: [UIView], topAnchor: NSLayoutYAxisAnchor? = nil, bottomAnchor: NSLayoutYAxisAnchor? = nil, constant: CGFloat = 0) { for view in views { - guard let superView = view.superview else { - return - } + guard let superView = view.superview else { return } + let top = topAnchor ?? superView.layoutMarginsGuide.topAnchor + let bottom = bottomAnchor ?? superView.layoutMarginsGuide.bottomAnchor view.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true - view.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true - superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true + view.topAnchor.constraint(greaterThanOrEqualTo: top).isActive = true + bottom.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true - var constraint = view.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor) + var constraint = view.topAnchor.constraint(equalTo: top) constraint.priority = .defaultLow constraint.isActive = true - constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor) + constraint = bottom.constraint(equalTo: view.bottomAnchor) constraint.priority = .defaultLow constraint.isActive = true } } - /// Pins the views vertically in the super view, allowing the super to expand depending on the tallest view. Shorter views are aligned top. - static func pinViewsVerticalExpandableAlignTop(_ views: [UIView]) { + /// Pins the views vertically to the top and bottom anchor, allowing the super to expand depending on the tallest view. Shorter views are aligned top. + static func pinViewsVerticalExpandableAlignTop(_ views: [UIView], topAnchor: NSLayoutYAxisAnchor? = nil, bottomAnchor: NSLayoutYAxisAnchor? = nil, constant: CGFloat = 0) { for view in views { - guard let superView = view.superview else { - return - } - view.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor).isActive = true - superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true + guard let superView = view.superview else { return } + let top = topAnchor ?? superView.layoutMarginsGuide.topAnchor + let bottom = bottomAnchor ?? superView.layoutMarginsGuide.bottomAnchor + view.topAnchor.constraint(equalTo: top).isActive = true + bottom.constraint(greaterThanOrEqualTo: view.bottomAnchor, constant: constant).isActive = true - let constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor) + let constraint = bottom.constraint(equalTo: view.bottomAnchor) constraint.priority = .defaultLow constraint.isActive = true } } /// Pins a view to the left and a view to the right, flexible space in between. The super can expand depending on the taller view. Shorter views are aligned top if alignTop true, else aligned center. - static func pinViews(leftView: UIView, rightView: UIView, alignTop: Bool) { + static func pinViews(leftView: UIView, rightView: UIView, alignTop: Bool, topAnchor: NSLayoutYAxisAnchor? = nil, bottomAnchor: NSLayoutYAxisAnchor? = nil, constant: CGFloat = 0) { guard let superView = leftView.superview else { return } if alignTop { - pinViewsVerticalExpandableAlignTop([leftView, rightView]) + pinViewsVerticalExpandableAlignTop([leftView, rightView], topAnchor: topAnchor, bottomAnchor: bottomAnchor, constant: constant) } else { - pinViewsVerticalExpandableAlignCenter([leftView, rightView]) + pinViewsVerticalExpandableAlignCenter([leftView, rightView], topAnchor: topAnchor, bottomAnchor: bottomAnchor, constant: constant) } leftView.leadingAnchor.constraint(equalTo: superView.layoutMarginsGuide.leadingAnchor).isActive = true superView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightView.trailingAnchor).isActive = true diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 623b2f47..6e18e427 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -20,9 +20,7 @@ import UIKit navigationBar.shadowImage = UIImage() navigationBar.isOpaque = true navigationBar.tintColor = .black - if let font = MFFonts.mfFont75Bd(MFSizeObject(standardSize: 14, standardiPadPortraitSize: 16, iPadProLandscapeSize: 18)?.getValueBasedOnScreenSize() ?? 14) { - navigationBar.titleTextAttributes = [NSAttributedString.Key.font: font]; - } + navigationBar.titleTextAttributes = [NSAttributedString.Key.font: MFStyler.fontBoldBodySmall(false)]; } public static func setupNavigationController() -> Self? { diff --git a/MVMCoreUI/Containers/TabBarController/TopTabbar.m b/MVMCoreUI/Containers/TabBarController/TopTabbar.m index e9d77c77..4b89903f 100644 --- a/MVMCoreUI/Containers/TabBarController/TopTabbar.m +++ b/MVMCoreUI/Containers/TabBarController/TopTabbar.m @@ -338,7 +338,7 @@ static NSString * const COLLECTION_CELL_ID = @"cell"; #pragma mark - helper -- (void)pinHeight:(CGFloat)height; { +- (void)pinHeight:(CGFloat)height { self.heightConstraint.constant = height; [self setNeedsLayout]; [self layoutIfNeeded]; diff --git a/MVMCoreUI/Containers/Views/Container/Container.swift b/MVMCoreUI/Containers/Views/Container/Container.swift index 53abfda3..96e6c3e8 100644 --- a/MVMCoreUI/Containers/Views/Container/Container.swift +++ b/MVMCoreUI/Containers/Views/Container/Container.swift @@ -16,8 +16,8 @@ open class Container: View, ContainerProtocol { } // MARK:- ModelMoleculeViewProtocol - override open func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let containerModel = model as? ContainerModelProtocol else { return } containerHelper.set(with: containerModel, for: view as? MVMCoreUIViewConstrainingProtocol) } diff --git a/MVMCoreUI/Containers/Views/Container/ContainerModel.swift b/MVMCoreUI/Containers/Views/Container/ContainerModel.swift index a5e89adb..a18e8589 100644 --- a/MVMCoreUI/Containers/Views/Container/ContainerModel.swift +++ b/MVMCoreUI/Containers/Views/Container/ContainerModel.swift @@ -8,7 +8,7 @@ import Foundation -public class ContainerModel: ContainerModelProtocol, Codable { +open class ContainerModel: ContainerModelProtocol, Codable { public var horizontalAlignment: UIStackView.Alignment? public var verticalAlignment: UIStackView.Alignment? public var useHorizontalMargins: Bool? @@ -48,7 +48,7 @@ public class ContainerModel: ContainerModelProtocol, Codable { bottomMarginPadding = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .bottomMarginPadding) } - public func encode(to encoder: Encoder) throws { + open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: verticalAlignment), forKey: .verticalAlignment) try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: horizontalAlignment), forKey: .horizontalAlignment) diff --git a/MVMCoreUI/Containers/Views/EntryFieldContainer.swift b/MVMCoreUI/Containers/Views/EntryFieldContainer.swift index 3f80006a..773721f7 100644 --- a/MVMCoreUI/Containers/Views/EntryFieldContainer.swift +++ b/MVMCoreUI/Containers/Views/EntryFieldContainer.swift @@ -276,8 +276,8 @@ import UIKit // MARK: - MVMCoreUIMoleculeViewProtocol //-------------------------------------------------- - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) self.delegateObject = delegateObject } } diff --git a/MVMCoreUI/Containers/Views/MoleculeContainer.swift b/MVMCoreUI/Containers/Views/MoleculeContainer.swift index d179ef72..f98451dd 100644 --- a/MVMCoreUI/Containers/Views/MoleculeContainer.swift +++ b/MVMCoreUI/Containers/Views/MoleculeContainer.swift @@ -30,40 +30,40 @@ open class MoleculeContainer: Container { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { if let casteModel = model as? MoleculeContainerModelProtocol { if view != nil { - (view as? ModelMoleculeViewProtocol)?.setWithModel(casteModel.molecule, delegateObject, additionalData) + (view as? ModelMoleculeViewProtocol)?.set(with: casteModel.molecule, delegateObject, additionalData) } else { if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(casteModel.molecule, delegateObject) { addMolecule(molecule) } } } - super.setWithModel(model, delegateObject, additionalData) + super.set(with: model, delegateObject, additionalData) } - public override static func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { + public override static func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { guard let containerModel = model as? MoleculeContainerModelProtocol, let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(containerModel.molecule) as? ModelMoleculeViewProtocol.Type, - let moleculeName = moleculeClass.nameForReuse(containerModel.molecule, delegateObject) else { - return "\(model?.moleculeName ?? "moleculeContainer")<>" + let moleculeName = moleculeClass.nameForReuse(with: containerModel.molecule, delegateObject) else { + return "\(model.moleculeName ?? "moleculeContainer")<>" } - return "\(model?.moleculeName ?? "moleculeContainer")<\(moleculeName)>" + return "\(model.moleculeName ?? "moleculeContainer")<\(moleculeName)>" } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - guard let containerModel = molecule as? MoleculeContainerModelProtocol else { return 0 } + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + guard let containerModel = model as? MoleculeContainerModelProtocol else { return 0 } guard let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(containerModel.molecule) as? ModelMoleculeViewProtocol.Type, - let moleculeHeight = moleculeClass.estimatedHeight(forRow: containerModel.molecule, delegateObject: delegateObject) else { + let moleculeHeight = moleculeClass.estimatedHeight(with: containerModel.molecule, delegateObject) else { return (containerModel.topMarginPadding ?? 0) + (containerModel.bottomMarginPadding ?? 0) } return moleculeHeight + (containerModel.topMarginPadding ?? 0) + (containerModel.bottomMarginPadding ?? 0) } - public override class func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { - guard let containerModel = molecule as? MoleculeContainerModelProtocol, + public override class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { + guard let containerModel = model as? MoleculeContainerModelProtocol, let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(containerModel.molecule) as? ModelMoleculeViewProtocol.Type else { return nil } - return moleculeClass.requiredModules(containerModel.molecule, delegateObject: delegateObject, error: error) + return moleculeClass.requiredModules(with: containerModel.molecule, delegateObject, error: error) } } diff --git a/MVMCoreUI/CustomPrimitives/Color.swift b/MVMCoreUI/CustomPrimitives/Color.swift index 165fa8ad..f06b337c 100644 --- a/MVMCoreUI/CustomPrimitives/Color.swift +++ b/MVMCoreUI/CustomPrimitives/Color.swift @@ -62,6 +62,14 @@ public final class Color: Codable { determineRGBA() } + public init?(colorString: String) throws { + let components = try Color.getColorComponents(for: colorString) + self.uiColor = components.color + hex = components.hex + name = components.name ?? "" + determineRGBA() + } + //-------------------------------------------------- // MARK: - Codable Initializers //-------------------------------------------------- @@ -69,21 +77,10 @@ public final class Color: Codable { required public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() let colorString = try container.decode(String.self) - - if colorString.hasPrefix("#") { - hex = colorString.replacingOccurrences(of: "#", with: "") - } else { - guard let hex = UIColor.names[colorString]?.hex else { throw ColorError.badName(reason: "Check the spelling of your color.") } - self.hex = hex.replacingOccurrences(of: "#", with: "") - name = colorString - } - - if hex.count == 8 { - uiColor = UIColor.getColorWithTransparencyBy(hex: hex) - } else { - uiColor = UIColor.getColorBy(hex: hex) - } - + let components = try Color.getColorComponents(for: colorString) + self.uiColor = components.color + hex = components.hex + name = components.name ?? "" determineRGBA() } @@ -95,6 +92,25 @@ public final class Color: Codable { //-------------------------------------------------- // MARK: - Methods //-------------------------------------------------- + private static func getColorComponents(for colorString: String) throws -> (color: UIColor, hex: String, name: String?) { + var color: UIColor + var hex: String + var name: String? + if colorString.hasPrefix("#") { + hex = colorString.replacingOccurrences(of: "#", with: "") + } else { + guard let hexString = UIColor.names[colorString]?.hex else { throw ColorError.badName(reason: "Check the spelling of your color.") } + hex = hexString.replacingOccurrences(of: "#", with: "") + name = colorString + } + + if hex.count == 8 { + color = UIColor.getColorWithTransparencyBy(hex: hex) + } else { + color = UIColor.getColorBy(hex: hex) + } + return (color, hex, name) + } public func convertHexToFloat(start: String.Index, end: String.Index) -> CGFloat { diff --git a/MVMCoreUI/FormUIHelpers/FormValidator.swift b/MVMCoreUI/FormUIHelpers/FormValidator.swift index 8cb3d774..cff26347 100644 --- a/MVMCoreUI/FormUIHelpers/FormValidator.swift +++ b/MVMCoreUI/FormUIHelpers/FormValidator.swift @@ -16,7 +16,7 @@ import MVMCore weak var delegate: FormValidationProtocol? var fieldMolecules: [FormValidationFormFieldProtocol] = [] var enableDisableMolecules: [FormValidationEnableDisableProtocol] = [] - var radioButtonsModelByGroup: [String: RadioButtonModel] = [:] + var radioButtonsModelByGroup: [String: RadioButtonSelectionHelper] = [:] public func insertMolecule(_ molecule: FormValidationProtocol) { if let molecule = molecule as? FormValidationFormFieldProtocol { diff --git a/MVMCoreUI/Legacy/Views/MVMCoreUIPageControl.h b/MVMCoreUI/Legacy/Views/MVMCoreUIPageControl.h index af699ddc..e86d3f9e 100644 --- a/MVMCoreUI/Legacy/Views/MVMCoreUIPageControl.h +++ b/MVMCoreUI/Legacy/Views/MVMCoreUIPageControl.h @@ -23,6 +23,7 @@ @property (nullable, weak, nonatomic) UIView *containerView; @property (nullable, weak, nonatomic) UIView *indicatorRectangle; @property (nullable, copy, nonatomic) PagingTouchBlock pagingTouchBlock; +@property (nullable, strong, nonatomic) UITapGestureRecognizer *tapGestureRecognizer; ///set YES to make the accessibility value as "Slide #currentPage of #totalPage", otherwise will be "Page #currentPage of #totalPage", default is NO @property (nonatomic) BOOL isSlidesAcc; diff --git a/MVMCoreUI/Legacy/Views/MVMCoreUIPageControl.m b/MVMCoreUI/Legacy/Views/MVMCoreUIPageControl.m index 6648b513..9a8f880f 100644 --- a/MVMCoreUI/Legacy/Views/MVMCoreUIPageControl.m +++ b/MVMCoreUI/Legacy/Views/MVMCoreUIPageControl.m @@ -267,6 +267,7 @@ static CGFloat const IndicatorRectangleHeight = 4; UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] init]; [tapGesture addTarget:self action:@selector(rectangleTapped:)]; [self addGestureRecognizer:tapGesture]; + self.tapGestureRecognizer = tapGesture; } } diff --git a/MVMCoreUI/MVMCoreUI.h b/MVMCoreUI/MVMCoreUI.h index 1b2183aa..5e8c92cc 100644 --- a/MVMCoreUI/MVMCoreUI.h +++ b/MVMCoreUI/MVMCoreUI.h @@ -32,6 +32,7 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[]; #pragma mark - Categories #import #import +#import #pragma mark - Styles #import diff --git a/MVMCoreUI/Models/ModelProtocols/FormModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/FormModelProtocol.swift index 1224d5a9..28840f06 100644 --- a/MVMCoreUI/Models/ModelProtocols/FormModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/FormModelProtocol.swift @@ -9,7 +9,7 @@ import Foundation -public protocol FormModelProtocol: Model { +public protocol FormModelProtocol: ModelProtocol { var required: Bool? { get } var fieldKey: String? { get } var groupName: String? { get } diff --git a/MVMCoreUI/Models/ModelProtocols/MoleculeModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/MoleculeModelProtocol.swift index cec7b90a..2928cf2a 100644 --- a/MVMCoreUI/Models/ModelProtocols/MoleculeModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/MoleculeModelProtocol.swift @@ -1,7 +1,7 @@ import Foundation -public protocol MoleculeModelProtocol: Model { +public protocol MoleculeModelProtocol: ModelProtocol { var moleculeName: String? { get } var backgroundColor: Color? { get set } } diff --git a/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift index 793baa0a..3ed37d6b 100644 --- a/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift @@ -9,7 +9,7 @@ import Foundation -public protocol TemplateModelProtocol: PageModelProtocol, Model { +public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol { var template: String { get } } diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift index 0dad7228..8d7fb539 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift @@ -11,30 +11,36 @@ import Foundation @objcMembers open class ListLeftVariableCheckboxAllTextAndLinks: TableViewCell { public let checkbox = Checkbox(frame: .zero) public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) - public let stack = Stack(frame: .zero) + public var stack: Stack + + // MARK: - Initializers + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: checkbox, model: StackItemModel(horizontalAlignment: .fill)), + (view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))], + axis: .horizontal) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } // MARK: - View Lifecycle override open func setupView() { super.setupView() - stack.stackItems = [StackItem(andContain: checkbox),StackItem(andContain: eyebrowHeadlineBodyLink)] addMolecule(stack) - } - - // MARK:- MVMCoreUIMoleculeViewProtocol - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) - guard let model = model as? ListLeftVariableCheckboxAllTextAndLinksModel else { return} - checkbox.setWithModel(model.checkbox, delegateObject, additionalData) - eyebrowHeadlineBodyLink.setWithModel(model.eyebrowHeadlineBodyLink, delegateObject, additionalData) - - let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .fill), - StackItemModel(horizontalAlignment: .leading)], - axis: .horizontal) - stack.model = stackModel stack.restack() } - open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + // MARK:- MVMCoreUIMoleculeViewProtocol + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListLeftVariableCheckboxAllTextAndLinksModel else { return} + checkbox.set(with: model.checkbox, delegateObject, additionalData) + eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 140 } } diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinksModel.swift b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinksModel.swift index fec71c0b..d3d3aab4 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinksModel.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinksModel.swift @@ -8,31 +8,49 @@ import Foundation -public class ListLeftVariableCheckboxAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol { - public static var identifier: String = "listLVCB" +open class ListLeftVariableCheckboxAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + open class var identifier: String { + return "listLVCB" + } public var checkbox: CheckboxModel public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(checkbox: CheckboxModel, eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel) { self.checkbox = checkbox self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink super.init() } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case eyebrowHeadlineBodyLink case checkbox } - + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink) checkbox = try typeContainer.decodeIfPresent(CheckboxModel.self, forKey: .checkbox) ?? CheckboxModel() try super.init(from: decoder) } - - public override func encode(to encoder: Encoder) throws { + + open override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift index 058d0da3..670624ad 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift @@ -17,39 +17,46 @@ import UIKit let leftImage = MFLoadImageView(pinnedEdges: .all) let leftLabel = Label.commonLabelB2(true) let rightLabel = Label.commonLabelB2(true) - let stack = Stack(frame: .zero) + var stack: Stack + + //----------------------------------------------------- + // MARK: - Initializers + //----------------------------------------------------- + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: leftImage, model: StackItemModel(horizontalAlignment: .fill)), + (view: leftLabel, model: StackItemModel(horizontalAlignment: .fill)), + (view: rightLabel, model: StackItemModel(spacing: 4, horizontalAlignment: .trailing))], + axis: .horizontal) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } //----------------------------------------------------- // MARK: - View Lifecycle //------------------------------------------------------- - override open func setupView() { super.setupView() - stack.stackItems = [StackItem(andContain: leftImage),StackItem(andContain: leftLabel),StackItem(andContain: rightLabel)] - addMolecule(stack) leftLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 901), for: .horizontal) rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 902), for: .horizontal) + addMolecule(stack) + stack.restack() } //---------------------------------------------------- // MARK: - Molecule //------------------------------------------------------ - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? ListLeftVariableIconWithRightCaretModel else { return} - leftImage.setWithModel(model.image, delegateObject, additionalData) - leftLabel.setWithModel(model.leftLabel, delegateObject, additionalData) - rightLabel.setWithModel(model.rightLabel, delegateObject, additionalData) - - let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .fill), - StackItemModel(horizontalAlignment: .fill), - StackItemModel(horizontalAlignment: .trailing)], - axis: .horizontal) - stack.model = stackModel - stack.restack() + leftImage.set(with: model.image, delegateObject, additionalData) + leftLabel.set(with: model.leftLabel, delegateObject, additionalData) + rightLabel.set(with: model.rightLabel, delegateObject, additionalData) } - open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 90 } diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift new file mode 100644 index 00000000..b4bb2fc3 --- /dev/null +++ b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift @@ -0,0 +1,67 @@ +// +// ListLeftVariableRadioButtonAndPaymentMethod.swift +// MVMCoreUI +// +// Created by Kruthika KP on 27/02/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers open class ListLeftVariableRadioButtonAndPaymentMethod: TableViewCell { + + //----------------------------------------------------- + // MARK: - Outlets + //----------------------------------------------------- + let radioButton = RadioButton(frame: .zero) + let leftImage = MFLoadImageView(pinnedEdges: .all) + let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink() + var stack: Stack + + //----------------------------------------------------- + // MARK: - Initializers + //----------------------------------------------------- + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: radioButton, model: StackItemModel(horizontalAlignment: .fill)), + (view: leftImage, model: StackItemModel(horizontalAlignment: .fill)), + (view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))], + axis: .horizontal) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + //----------------------------------------------------- + // MARK: - View Lifecycle + //----------------------------------------------------- + override open func setupView() { + super.setupView() + addMolecule(stack) + stack.restack() + eyebrowHeadlineBodyLink.body.textColor = .mvmOrangeAA + eyebrowHeadlineBodyLink.headline.styleBoldBodySmall(true) + } + + open override func reset() { + super.reset() + eyebrowHeadlineBodyLink.body.textColor = .mvmOrangeAA + eyebrowHeadlineBodyLink.headline.styleBoldBodySmall(true) + } + + //---------------------------------------------------- + // MARK: - Molecule + //---------------------------------------------------- + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListLeftVariableRadioButtonAndPaymentMethodModel else { return} + radioButton.set(with: model.radioButton, delegateObject, additionalData) + leftImage.set(with: model.image, delegateObject, additionalData) + eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 90 + } +} diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethodModel.swift b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethodModel.swift new file mode 100644 index 00000000..5ea28778 --- /dev/null +++ b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethodModel.swift @@ -0,0 +1,55 @@ +// +// ListLeftVariableRadioButtonAndPaymentMethodModel.swift +// MVMCoreUI +// +// Created by Kruthika KP on 27/02/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class ListLeftVariableRadioButtonAndPaymentMethodModel: ListItemModel, MoleculeModelProtocol { + public static var identifier: String = "listLVRBImg" + public var radioButton: RadioButtonModel + public var image: ImageViewModel + public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel + + public init(radioButton: RadioButtonModel, image: ImageViewModel, eyebrowHeadlineBodyLink:EyebrowHeadlineBodyLinkModel) { + self.radioButton = radioButton + self.image = image + self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink + super.init() + } + + public override func setDefaults() { + super.setDefaults() + if image.width == nil, image.height == nil { + image.width = 32 + image.height = 32 + } + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case radioButton + case image + case eyebrowHeadlineBodyLink + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + radioButton = try typeContainer.decode(RadioButtonModel.self, forKey: .radioButton) + image = try typeContainer.decode(ImageViewModel.self, forKey: .image) + eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(radioButton, forKey: .radioButton) + try container.encode(image, forKey: .image) + try container.encode(eyebrowHeadlineBodyLink, forKey: .eyebrowHeadlineBodyLink) + } +} diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift b/MVMCoreUI/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift new file mode 100644 index 00000000..1ea1a4a9 --- /dev/null +++ b/MVMCoreUI/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift @@ -0,0 +1,74 @@ +// +// ListOneColumnFullWidthTextAllTextAndLinks.swift +// MVMCoreUI +// +// Created by Kruthika KP on 14/02/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers public class ListOneColumnFullWidthTextAllTextAndLinks: TableViewCell { + + //----------------------------------------------------- + // MARK: - Outlets + //----------------------------------------------------- + var stack: Stack + let eyebrow = Label.commonLabelB3(true) + let headline = Label.commonLabelH3(true) + let subHeadline = Label.commonLabelB1(true) + let body = Label.commonLabelB2(true) + let link = Link() + + //----------------------------------------------------- + // MARK: - Initializers + //----------------------------------------------------- + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [eyebrow, headline, subHeadline, body, link]) + stack.stackModel?.spacing = 0 + stack.stackModel?.molecules[4].spacing = 2 + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + //----------------------------------------------------- + // MARK: - View Lifecycle + //----------------------------------------------------- + override open func setupView() { + super.setupView() + addMolecule(stack) + } + + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?){ + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListOneColumnFullWidthTextAllTextAndLinksModel else { return } + eyebrow.setOptional(with: model.eyebrow, delegateObject, additionalData) + headline.setOptional(with: model.headline, delegateObject, additionalData) + subHeadline.setOptional(with: model.subHeadline, delegateObject, additionalData) + body.setOptional(with: model.body, delegateObject, additionalData) + link.setOptional(with: 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? { + return 90 + } + + open override func reset() { + super.reset() + eyebrow.styleB3(true) + headline.styleH3(true) + subHeadline.styleB1(true) + body.styleB2(true) + } +} diff --git a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnFullWidthTextAllTextAndLinksModel.swift b/MVMCoreUI/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinksModel.swift similarity index 100% rename from MVMCoreUI/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnFullWidthTextAllTextAndLinksModel.swift rename to MVMCoreUI/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinksModel.swift diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRVWheel.swift b/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRVWheel.swift index 46d4b955..5ad5d182 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRVWheel.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRVWheel.swift @@ -11,7 +11,22 @@ import Foundation let wheel = GraphView(frame: .zero) let leftLabel = Label.commonLabelB1(true) let rightLabel = Label.commonLabelB2(true) - let stack = Stack(frame: .zero) + var stack: Stack + + //----------------------------------------------------- + // MARK: - Initializers + //----------------------------------------------------- + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: leftLabel, model: StackItemModel(horizontalAlignment: .leading)), + (view: wheel, model: StackItemModel(horizontalAlignment: .fill)), + (view: rightLabel, model: StackItemModel(spacing: 4, horizontalAlignment: .fill))], + axis: .horizontal) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } //------------------------------------------------- // MARK: - Setup @@ -19,26 +34,19 @@ import Foundation open override func setupView() { super.setupView() rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal) - stack.stackItems = [StackItem(andContain: leftLabel),StackItem(andContain: wheel),StackItem(andContain: rightLabel)] addMolecule(stack) + stack.restack() } //------------------------------------------------- // MARK: - ModelMoleculeViewProtocol //------------------------------------------------- - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? ListRVWheelModel else { return } - leftLabel.setWithModel(model.leftLabel, delegateObject, additionalData) - rightLabel.setWithModel(model.rightLabel, delegateObject, additionalData) - wheel.setWithModel(model.wheel, delegateObject, additionalData) - - let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .leading), - StackItemModel(horizontalAlignment: .fill), - StackItemModel(spacing: 4, horizontalAlignment: .fill)], - axis: .horizontal) - stack.model = stackModel - stack.restack() + leftLabel.set(with: model.leftLabel, delegateObject, additionalData) + rightLabel.set(with: model.rightLabel, delegateObject, additionalData) + wheel.set(with: model.wheel, delegateObject, additionalData) } //------------------------------------------------- @@ -50,7 +58,7 @@ import Foundation rightLabel.styleB2(true) } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 70 } } diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePayments.swift b/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePayments.swift index 66f88371..9cfccd04 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePayments.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePayments.swift @@ -15,34 +15,42 @@ import Foundation //------------------------------------------------------- let leftLabel = Label.commonLabelB1(true) let rightImage = MFLoadImageView(pinnedEdges: .all) - let stack = Stack(frame: .zero) + var stack: Stack + + //----------------------------------------------------- + // MARK: - Initializers + //----------------------------------------------------- + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: leftLabel, model: StackItemModel(horizontalAlignment: .leading)), + (view: rightImage, model: StackItemModel(horizontalAlignment: .fill))], + axis: .horizontal) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } //----------------------------------------------------- // MARK: - View Lifecycle //------------------------------------------------------- override open func setupView() { super.setupView() - stack.stackItems = [StackItem(andContain: leftLabel),StackItem(andContain: rightImage)] addMolecule(stack) + stack.restack() } //---------------------------------------------------- // MARK: - Molecule //------------------------------------------------------ - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? ListRightVariablePaymentsModel else { return } - leftLabel.setWithModel(model.leftLabel, delegateObject, additionalData) - rightImage.setWithModel(model.image, delegateObject, additionalData) - - let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .leading), - StackItemModel(horizontalAlignment: .fill)], - axis: .horizontal) - stack.model = stackModel - stack.restack() + leftLabel.set(with: model.leftLabel, delegateObject, additionalData) + rightImage.set(with: model.image, delegateObject, additionalData) } - open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 65 } diff --git a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/FourColumn/ListFourColumnDataUsageDivider.swift b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/FourColumn/ListFourColumnDataUsageDivider.swift new file mode 100644 index 00000000..35968599 --- /dev/null +++ b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/FourColumn/ListFourColumnDataUsageDivider.swift @@ -0,0 +1,63 @@ +// +// ListFourColumnDataUsageDivider.swift +// MVMCoreUI +// +// Created by Lekshmi S on 18/02/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class ListFourColumnDataUsageDivider: TableViewCell { + + // MARK: - MFViewProtocol + let label1 = Label.createLabelBoldBodySmall(true) + let label2 = Label.createLabelBoldBodySmall(true) + let label3 = Label.createLabelBoldBodySmall(true) + let label4 = Label.createLabelBoldBodySmall(true) + var stack: Stack + + // MARK: - Initializers + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: label1, model: StackItemModel(percent: 19, horizontalAlignment: .leading)), + (view: label2, model: StackItemModel(percent: 44, horizontalAlignment: .leading)), + (view: label3, model: StackItemModel(percent: 17, horizontalAlignment: .leading)), + (view: label4, model: StackItemModel(percent: 20, horizontalAlignment: .leading))], + axis: .horizontal, spacing: 8) + 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() + } + + // MARK: - MVMCoreUIMoleculeViewProtocol + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListFourColumnDataUsageDividerModel else { return } + label1.set(with: model.label1, delegateObject, additionalData) + label2.set(with: model.label2, delegateObject, additionalData) + label3.set(with: model.label3, delegateObject, additionalData) + label4.set(with: model.label4, delegateObject, additionalData) + } + + // MARK: - MVMCoreUIMoleculeViewProtocol + open override func reset() { + super.reset() + label1.styleBoldBodySmall(true) + label2.styleBoldBodySmall(true) + label3.styleBoldBodySmall(true) + label4.styleBoldBodySmall(true) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 121 + } +} diff --git a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/FourColumn/ListFourColumnDataUsageDividerModel.swift b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/FourColumn/ListFourColumnDataUsageDividerModel.swift new file mode 100644 index 00000000..f9ce88d8 --- /dev/null +++ b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/FourColumn/ListFourColumnDataUsageDividerModel.swift @@ -0,0 +1,58 @@ +// +// ListFourColumnDataUsageDividerModel.swift +// MVMCoreUI +// +// Created by Lekshmi S on 18/02/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class ListFourColumnDataUsageDividerModel: ListItemModel, MoleculeModelProtocol { + public static var identifier: String = "list4CDiv" + public var label1: LabelModel + public var label2: LabelModel + public var label3: LabelModel + public var label4: LabelModel + + public init(label1: LabelModel, label2: LabelModel, label3: LabelModel, label4: LabelModel) { + self.label1 = label1 + self.label2 = label2 + self.label3 = label3 + self.label4 = label4 + super.init() + } + + /// Defaults to set + override public func setDefaults() { + super.setDefaults() + style = "tallDivider" + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case label1 + case label2 + case label3 + case label4 + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + label1 = try typeContainer.decode(LabelModel.self, forKey: .label1) + label2 = try typeContainer.decode(LabelModel.self, forKey: .label2) + label3 = try typeContainer.decode(LabelModel.self, forKey: .label3) + label4 = try typeContainer.decode(LabelModel.self, forKey: .label4) + 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(label1, forKey: .label1) + try container.encode(label2, forKey: .label2) + try container.encode(label3, forKey: .label3) + try container.encode(label4, forKey: .label4) + } +} diff --git a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift deleted file mode 100644 index 9e930396..00000000 --- a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift +++ /dev/null @@ -1,65 +0,0 @@ -// -// ListOneColumnFullWidthTextAllTextAndLinks.swift -// MVMCoreUI -// -// Created by Kruthika KP on 14/02/20. -// Copyright © 2020 Verizon Wireless. All rights reserved. -// - -import Foundation - -@objcMembers public class ListOneColumnFullWidthTextAllTextAndLinks: TableViewCell { - - //----------------------------------------------------- - // MARK: - Outlets - //----------------------------------------------------- - - let stack = Stack(frame: .zero) - let eyebrow = Label.commonLabelB3(true) - let headline = Label.commonLabelH3(true) - let subHeadline = Label.commonLabelB1(true) - let body = Label.commonLabelB2(true) - let link = Link() - - //----------------------------------------------------- - // MARK: - View Lifecycle - //------------------------------------------------------- - override open func setupView() { - super.setupView() - stack.stackItems = [StackItem(andContain: eyebrow), - StackItem(andContain: headline), - StackItem(andContain: subHeadline), - StackItem(andContain: body), - StackItem(andContain: link)] - addMolecule(stack) - } - - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?){ - super.setWithModel(model, delegateObject, additionalData) - guard let model = model as? ListOneColumnFullWidthTextAllTextAndLinksModel else { return} - eyebrow.setWithModel(model.eyebrow, delegateObject, additionalData) - headline.setWithModel(model.headline, delegateObject, additionalData) - subHeadline.setWithModel(model.subHeadline, delegateObject, additionalData) - body.setWithModel(model.body, delegateObject, additionalData) - link.setWithModel(model.link, delegateObject, additionalData) - let stackModel = StackModel(molecules: [StackItemModel(spacing: 2, gone: !eyebrow.hasText), - StackItemModel(spacing: 2, gone: !headline.hasText), - StackItemModel(spacing: 2, gone: !subHeadline.hasText), - StackItemModel(spacing: 2, gone: !body.hasText), - StackItemModel(spacing: 2, gone: (link.titleLabel?.text?.count ?? 0) == 0)]) - stack.model = stackModel - stack.restack() - } - - open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat?{ - return 90 - } - - open override func reset() { - super.reset() - eyebrow.styleB3(true) - headline.styleH3(true) - subHeadline.styleB1(true) - body.styleB2(true) - } -} diff --git a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift index 565ed737..9adbe531 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift @@ -13,35 +13,38 @@ import Foundation let leftHeadlineBody = HeadlineBody(frame: .zero) let centerHeadLineBody = HeadlineBody(frame: .zero) let rightHeadLineBody = HeadlineBody(frame: .zero) - let stack = Stack(frame: .zero) + var stack: Stack + + // MARK: - Initializers + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: leftHeadlineBody, model: StackItemModel(percent: 33, horizontalAlignment: .leading)), + (view: centerHeadLineBody, model: StackItemModel(percent: 34, horizontalAlignment: .center)), + (view: rightHeadLineBody, model: StackItemModel(percent: 33, horizontalAlignment: .trailing))], + 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() - - //using stackItems to align the three headlineBody - stack.stackItems = [StackItem(andContain: leftHeadlineBody),StackItem(andContain: centerHeadLineBody),StackItem(andContain: rightHeadLineBody)] addMolecule(stack) + stack.restack() } // MARK: - MVMCoreUIMoleculeViewProtocol - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? ListThreeColumnPlanDataDividerModel else { return } - leftHeadlineBody.setWithModel(model.leftHeadlineBody, delegateObject, additionalData) - centerHeadLineBody.setWithModel(model.centerHeadlineBody, delegateObject, additionalData) - rightHeadLineBody.setWithModel(model.rightHeadlineBody, delegateObject, additionalData) - - // Create a stack model to use for the internal stack and set the alignment of models - let stackModel = StackModel(molecules: [StackItemModel(percent: 33, horizontalAlignment: .leading), - StackItemModel(percent: 34, horizontalAlignment: .center), - StackItemModel(percent: 33, horizontalAlignment: .trailing)], - axis: .horizontal) - stack.model = stackModel - stack.restack() + leftHeadlineBody.set(with: model.leftHeadlineBody, delegateObject, additionalData) + centerHeadLineBody.set(with: model.centerHeadlineBody, delegateObject, additionalData) + rightHeadLineBody.set(with: model.rightHeadlineBody, delegateObject, additionalData) } - open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { return 121 } } diff --git a/MVMCoreUI/Molecules/Doughnut/DoughnutChart.swift b/MVMCoreUI/Molecules/Doughnut/DoughnutChart.swift index cbb6aeba..acaa0923 100644 --- a/MVMCoreUI/Molecules/Doughnut/DoughnutChart.swift +++ b/MVMCoreUI/Molecules/Doughnut/DoughnutChart.swift @@ -94,14 +94,14 @@ open class DoughnutChart: View { doughnutLayer.transform = CATransform3DMakeRotation(1 * .pi, 0.0, 0.0, 1.0) } - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) clearLayers() guard let doughnutChartModel = doughnutChartModel else { return } - titleLabel.setWithModel(doughnutChartModel.title, delegateObject, additionalData) - subTitleLabel.setWithModel(doughnutChartModel.subtitle, delegateObject, additionalData) + titleLabel.setOptional(with: doughnutChartModel.title, delegateObject, additionalData) + subTitleLabel.setOptional(with: doughnutChartModel.subtitle, delegateObject, additionalData) titleLabel.textAlignment = .center subTitleLabel.textAlignment = .center updateLabelContainer() diff --git a/MVMCoreUI/Molecules/Doughnut/DoughnutChartView.swift b/MVMCoreUI/Molecules/Doughnut/DoughnutChartView.swift index 6bf91a43..7d279759 100644 --- a/MVMCoreUI/Molecules/Doughnut/DoughnutChartView.swift +++ b/MVMCoreUI/Molecules/Doughnut/DoughnutChartView.swift @@ -65,11 +65,11 @@ import Foundation colorLablesStack.reset() } - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = doughnutChartModel else { return } - doughnutChart.setWithModel(model, delegateObject, additionalData) + doughnutChart.set(with: model, delegateObject, additionalData) // Create the stack model var stackItems: [MoleculeStackItemModel] = [] @@ -78,12 +78,12 @@ import Foundation } let stack = MoleculeStackModel(molecules: stackItems) stack.verticalAlignment = .fill - colorLablesStack.setWithModel(stack, delegateObject, additionalData) + colorLablesStack.set(with: stack, delegateObject, additionalData) } open override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { guard let json = json, let model = try? Self.decodeJSONToModel(json: json, type: DoughnutChartModel.self) else { return } - setWithModel(model, delegateObject, additionalData) + set(with: model, delegateObject, additionalData) } } @@ -94,12 +94,12 @@ extension DoughnutChartView: MVMCoreUIViewConstrainingProtocol { } class ColorViewLabelsStack: MoleculeStackView { - override func createStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + override func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { guard let stackItemModels = stackModel?.molecules else { return } for model in stackItemModels { let view = ColorViewWithLabel() let stackItem = MoleculeStackItem(andContain: view) - stackItem.setWithModel(model, delegateObject, additionalData) + stackItem.set(with: model, delegateObject, additionalData) stackItems.append(stackItem) } } @@ -149,12 +149,12 @@ class ColorViewWithLabel: View { label.setAsMolecule() } - override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) + override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) guard let chartItemModel = model as? DoughnutChartItemModel else { return } - label.setWithModel(chartItemModel.label, delegateObject, additionalData) + label.set(with: chartItemModel.label, delegateObject, additionalData) colorView.backgroundColor = chartItemModel.color.uiColor } } diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/ImageHeadlineBody.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/ImageHeadlineBody.swift index 840f4763..469b1929 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/ImageHeadlineBody.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/ImageHeadlineBody.swift @@ -51,14 +51,14 @@ import UIKit } // MARK:- ModelMoleculeViewProtocol - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 95 } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? ImageHeadlineBodyModel else { return } - headlineBody.setWithModel(model.headlineBody, delegateObject, additionalData) - imageView.setWithModel(model.image, delegateObject, additionalData) + headlineBody.set(with: model.headlineBody, delegateObject, additionalData) + imageView.set(with: model.image, delegateObject, additionalData) } } diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift index be6228f8..50288c58 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -101,23 +101,24 @@ import UIKit } // MARK: - ModelMoleculeViewProtocol - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - guard let model = molecule as? TwoButtonViewModel else { return 0 } - return PillButton.estimatedHeight(forRow: model.primaryButton ?? model.secondaryButton, delegateObject: delegateObject) + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + guard let model = model as? TwoButtonViewModel, + let buttonModel = model.primaryButton ?? model.secondaryButton else { return 0 } + return PillButton.estimatedHeight(with: buttonModel, delegateObject) } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? TwoButtonViewModel else { return } if let secondaryModel = model.secondaryButton { showSecondaryButton() - secondaryButton.setWithModel(secondaryModel, delegateObject, additionalData) + secondaryButton.set(with: secondaryModel, delegateObject, additionalData) } else { hideSecondaryButton() } if let primaryModel = model.primaryButton { showPrimaryButton() - primaryButton.setWithModel(primaryModel, delegateObject, additionalData) + primaryButton.set(with: primaryModel, delegateObject, additionalData) } else { hidePrimaryButton() } diff --git a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift index 164bd2c3..f9b9d976 100644 --- a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift @@ -12,8 +12,6 @@ import UIKit //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - - var dropDownListItemModel: DropDownListItemModel? let dropDown = ItemDropdownEntryField() var delegateObject: MVMCoreUIDelegateObject? var previousIndex = NSNotFound @@ -31,7 +29,7 @@ import UIKit guard newValue != oldValue, let self = self, let index = self.dropDown.pickerData.firstIndex(of: newValue), - let dropListItemJSON = self.dropDownListItemModel.toJSON(), + let dropListItemJSON = (self.listItemModel as? DropDownListItemModel).toJSON(), let json2d = dropListItemJSON.optionalArrayForKey("molecules") as? [[[AnyHashable: Any]]] else { return } @@ -44,12 +42,12 @@ import UIKit } } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - dropDownListItemModel = model as? DropDownListItemModel + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { self.delegateObject = delegateObject - super.setWithModel(model, delegateObject, additionalData) - - dropDown.setWithModel(dropDownListItemModel?.dropDown, delegateObject, additionalData) + super.set(with: model, delegateObject, additionalData) + if let dropDownListItemModel = model as? DropDownListItemModel { + dropDown.set(with: dropDownListItemModel.dropDown, delegateObject, additionalData) + } dropDown.observingTextFieldDelegate = delegateObject?.uiTextFieldDelegate as? ObservingTextFieldDelegate dropDown.uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate } @@ -59,7 +57,7 @@ import UIKit bottomSeparatorView?.setStyle(.none) } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 80 } } diff --git a/MVMCoreUI/Molecules/Items/ListItemModel.swift b/MVMCoreUI/Molecules/Items/ListItemModel.swift index 973a487a..3ff483eb 100644 --- a/MVMCoreUI/Molecules/Items/ListItemModel.swift +++ b/MVMCoreUI/Molecules/Items/ListItemModel.swift @@ -9,13 +9,21 @@ import Foundation -@objcMembers public class ListItemModel: ContainerModel, ListItemModelProtocol { +@objcMembers open class ListItemModel: ContainerModel, ListItemModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public var backgroundColor: Color? public var action: ActionModelProtocol? public var hideArrow: Bool? public var line: LineModel? public var style: String? - + + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case backgroundColor case action @@ -24,8 +32,12 @@ import Foundation case style } + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + /// Defaults to set - public func setDefaults() { + open func setDefaults() { if useHorizontalMargins == nil { useHorizontalMargins = true } @@ -37,11 +49,19 @@ import Foundation } } + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public override init() { super.init() setDefaults() } - + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) @@ -52,8 +72,8 @@ import Foundation try super.init(from: decoder) setDefaults() } - - public override func encode(to encoder: Encoder) throws { + + open override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) @@ -63,4 +83,3 @@ import Foundation try container.encodeIfPresent(style, forKey: .style) } } - diff --git a/MVMCoreUI/Molecules/Items/MoleculeCollectionViewCell.swift b/MVMCoreUI/Molecules/Items/MoleculeCollectionViewCell.swift index 9d56f4cd..9c63ba64 100644 --- a/MVMCoreUI/Molecules/Items/MoleculeCollectionViewCell.swift +++ b/MVMCoreUI/Molecules/Items/MoleculeCollectionViewCell.swift @@ -68,7 +68,7 @@ open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeVi } - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let collectionModel = model as? CarouselItemModel else { return } @@ -98,7 +98,7 @@ open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeVi molecule = moleculeView } } else { - (molecule as? ModelMoleculeViewProtocol)?.setWithModel(collectionModel.molecule, delegateObject, additionalData) + (molecule as? ModelMoleculeViewProtocol)?.set(with: collectionModel.molecule, delegateObject, additionalData) } guard let molecule = molecule else { return } @@ -114,10 +114,10 @@ open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeVi backgroundColor = .white } - public class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { + public class func nameForReuse(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { guard let molecule = (model as? CarouselItemModel)?.molecule, let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(molecule) as? ModelMoleculeViewProtocol.Type, - let name = moleculeClass.nameForReuse(molecule, delegateObject) ?? molecule.moleculeName else { + let name = moleculeClass.nameForReuse(with: molecule, delegateObject) ?? molecule.moleculeName else { return nil } return name diff --git a/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift b/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift index 0416ce8e..f1d3794b 100644 --- a/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift @@ -13,13 +13,13 @@ import UIKit // MARK: - MVMCoreUIMoleculeViewProtocol - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? MoleculeListItemModel else { return } if molecule != nil { - (molecule as? ModelMoleculeViewProtocol)?.setWithModel(model.molecule, delegateObject, additionalData) + (molecule as? ModelMoleculeViewProtocol)?.set(with: model.molecule, delegateObject, additionalData) } else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(model.molecule, delegateObject, false) { addMolecule(moleculeView) @@ -28,11 +28,11 @@ import UIKit containerHelper.set(with: model, for: molecule as? MVMCoreUIViewConstrainingProtocol) } - public override class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { + public override class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { guard let moleculeModel = (model as? MoleculeListItemModel)?.molecule else { return "\(self)<>" } let className = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type - let moleculeName = className?.nameForReuse(moleculeModel, delegateObject) ?? moleculeModel.moleculeName ?? "" + let moleculeName = className?.nameForReuse(with: moleculeModel, delegateObject) ?? moleculeModel.moleculeName ?? "" return "\(self)<\(moleculeName)>" } @@ -45,10 +45,10 @@ import UIKit return theClass.requiredModules?(moleculeJSON, delegateObject: delegateObject, error: error) } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { - guard let moleculeModel = (molecule as? MoleculeContainerModel)?.molecule, + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + guard let moleculeModel = (model as? MoleculeContainerModel)?.molecule, let classType = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type, - let height = classType.estimatedHeight(forRow: moleculeModel, delegateObject: delegateObject) + let height = classType.estimatedHeight(with: moleculeModel, delegateObject) else { return 80 } return max(2 * PaddingDefaultVerticalSpacing3, height) diff --git a/MVMCoreUI/Molecules/Items/TabsTableViewCell.swift b/MVMCoreUI/Molecules/Items/TabsTableViewCell.swift index 8a971221..da700a28 100644 --- a/MVMCoreUI/Molecules/Items/TabsTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/TabsTableViewCell.swift @@ -36,8 +36,8 @@ import UIKit // MARK: - MoleculeDelegateProtocol - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) self.delegateObject = delegateObject tabs.reloadData() } @@ -47,7 +47,7 @@ import UIKit tabs.reset() } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 46 } } diff --git a/MVMCoreUI/Molecules/LeftRightViews/ActionDetailWithImage.swift b/MVMCoreUI/Molecules/LeftRightViews/ActionDetailWithImage.swift index bde18777..b550ad0d 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/ActionDetailWithImage.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ActionDetailWithImage.swift @@ -114,14 +114,14 @@ import UIKit } // MARK:- ModelMoleculeViewProtocol - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 197 } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? ActionDetailWithImageModel else { return } - headlineBodyButton.setWithModel(model.headlineBodyButton, delegateObject, additionalData) - imageLoader.setWithModel(model.image, delegateObject, additionalData) + headlineBodyButton.set(with: model.headlineBodyButton, delegateObject, additionalData) + imageLoader.set(with: model.image, delegateObject, additionalData) } } diff --git a/MVMCoreUI/Molecules/LeftRightViews/CornerLabels.swift b/MVMCoreUI/Molecules/LeftRightViews/CornerLabels.swift index 2de9deca..f7ae36de 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/CornerLabels.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/CornerLabels.swift @@ -166,19 +166,19 @@ import UIKit return 34 } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? CornerLabelsModel else { return } if middleView != nil { - (middleView as? ModelMoleculeViewProtocol)?.setWithModel(model, delegateObject, additionalData) + (middleView as? ModelMoleculeViewProtocol)?.set(with: model, delegateObject, additionalData) } else if let moleculeModel = model.molecule, let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(moleculeModel, delegateObject) { addMiddleView(molecule) } - topLeftLabel.setWithModel(model.topLeftLabel, delegateObject, additionalData) - topRightLabel.setWithModel(model.topRightLabel, delegateObject, additionalData) - bottomLeftLabel.setWithModel(model.bottomLeftLabel, delegateObject, additionalData) - bottomRightLabel.setWithModel(model.bottomRightLabel, delegateObject, additionalData) + topLeftLabel.setOptional(with: model.topLeftLabel, delegateObject, additionalData) + topRightLabel.setOptional(with: model.topRightLabel, delegateObject, additionalData) + bottomLeftLabel.setOptional(with: model.bottomLeftLabel, delegateObject, additionalData) + bottomRightLabel.setOptional(with: model.bottomRightLabel, delegateObject, additionalData) topLabelToMoleculeConstraint?.constant = (middleView != nil && (topLeftLabel.hasText || topRightLabel.hasText)) ? spaceAboveMolecule : 0 bottomLabelToMoleculeConstraint?.constant = (middleView != nil && (bottomLeftLabel.hasText || bottomRightLabel.hasText)) ? spaceBelowMolecule : 0 diff --git a/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggle.swift b/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggle.swift index 07639dbe..bfed52e4 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggle.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggle.swift @@ -38,15 +38,16 @@ import UIKit } // MARK:- ModelMoleculeViewProtocol - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? HeadlineBodyLinkToggleModel else { return } - headlineBodyLink.setWithModel(model.headlineBodyLink, delegateObject, additionalData) - toggle.setWithModel(model.toggle, delegateObject, additionalData) + headlineBodyLink.set(with: model.headlineBodyLink, delegateObject, additionalData) + toggle.set(with: model.toggle, delegateObject, additionalData) } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - return HeadlineBodyLink.estimatedHeight(forRow: (molecule as? HeadlineBodyLinkToggleModel)?.headlineBodyLink, delegateObject: delegateObject) + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + guard let model = model as? HeadlineBodyLinkToggleModel else { return nil } + return HeadlineBodyLink.estimatedHeight(with: model.headlineBodyLink, delegateObject) } } diff --git a/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggle.swift b/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggle.swift index 8df94fa8..bbfe0ffc 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggle.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggle.swift @@ -35,18 +35,18 @@ import UIKit } // MARK:- ModelMoleculeViewProtocol - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let headlineBodyToggleModel = model as? HeadlineBodyToggleModel else { return } setWithJSON(headlineBodyToggleModel.toJSON(), delegateObject: delegateObject, additionalData: additionalData) } - open class override func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - guard let model = molecule as? HeadlineBodyToggleModel, - let toggleHeight = Toggle.estimatedHeight(forRow: model.toggle, delegateObject: delegateObject), - let headlineBody = HeadlineBody.estimatedHeight(forRow: model.headlineBody, delegateObject: delegateObject) else { return nil } + open class override func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + guard let model = model as? HeadlineBodyToggleModel, + let toggleHeight = Toggle.estimatedHeight(with: model.toggle, delegateObject), + let headlineBody = HeadlineBody.estimatedHeight(with: model.headlineBody, delegateObject) else { return nil } return max(toggleHeight, headlineBody) } diff --git a/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift b/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift index f2925cc9..ccbdf9c3 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift @@ -32,19 +32,19 @@ import UIKit } // MARK:- ModelMoleculeViewProtocol - open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - guard let model = molecule as? LabelToggleModel, - let toggleHeight = Toggle.estimatedHeight(forRow: model.toggle, delegateObject: delegateObject), - let labelHeight = Label.estimatedHeight(forRow: model.label, delegateObject: delegateObject) else { return nil } + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + guard let model = model as? LabelToggleModel, + let toggleHeight = Toggle.estimatedHeight(with: model.toggle, delegateObject), + let labelHeight = Label.estimatedHeight(with: model.label, delegateObject) else { return nil } return max(toggleHeight, labelHeight) } - open override func setWithModel(_ 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 } - label.setWithModel(labelToggleModel.label, delegateObject, additionalData) - toggle.setWithModel(labelToggleModel.toggle, delegateObject, additionalData) + label.set(with: labelToggleModel.label, delegateObject, additionalData) + toggle.set(with: labelToggleModel.toggle, delegateObject, additionalData) } // MARK: - MVMCoreUIMoleculeViewProtocol diff --git a/MVMCoreUI/Molecules/ModelMoleculeViewProtocol.swift b/MVMCoreUI/Molecules/ModelMoleculeViewProtocol.swift index 972ee175..fbeadd96 100644 --- a/MVMCoreUI/Molecules/ModelMoleculeViewProtocol.swift +++ b/MVMCoreUI/Molecules/ModelMoleculeViewProtocol.swift @@ -9,20 +9,20 @@ import Foundation public protocol ModelMoleculeViewProtocol { - func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) - static func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? - static func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? - static func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? + func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) + static func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? + static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? + static func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? } extension ModelMoleculeViewProtocol { - public static func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { - return model?.moleculeName + public static func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { + return model.moleculeName } - public static func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return nil } - public static func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { + public static func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { return nil } // Temporary @@ -31,4 +31,10 @@ extension ModelMoleculeViewProtocol { let decoder = JSONDecoder() return try decoder.decode(type, from: data) } + + public func setOptional(with model: T?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + if let model = model { + set(with: model, delegateObject, additionalData) + } + } } diff --git a/MVMCoreUI/Molecules/ModuleMolecule.swift b/MVMCoreUI/Molecules/ModuleMolecule.swift index 360410b7..e92f41da 100644 --- a/MVMCoreUI/Molecules/ModuleMolecule.swift +++ b/MVMCoreUI/Molecules/ModuleMolecule.swift @@ -19,8 +19,8 @@ open class ModuleMolecule: Container { super.setupView() } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let moduleMoleculeModel = model as? ModuleMoleculeModel, let moduleModel = delegateObject?.moleculeDelegate?.getModuleWithName(moduleMoleculeModel.moduleName) else { @@ -42,36 +42,36 @@ open class ModuleMolecule: Container { } } } else { - moduleMolecule?.setWithModel(model, delegateObject, additionalData) + moduleMolecule?.set(with: model, delegateObject, additionalData) } } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - guard let moduleMolecule = molecule as? ModuleMoleculeModel, + guard let moduleMolecule = model as? ModuleMoleculeModel, let moduleModel = delegateObject?.moleculeDelegate?.getModuleWithName(moduleMolecule.moduleName), let classType = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moduleModel) as? ModelMoleculeViewProtocol.Type, - let height = classType.estimatedHeight(forRow: moduleModel, delegateObject: delegateObject)else { + let height = classType.estimatedHeight(with: moduleModel, delegateObject) else { // Critical error return 0 } return height } - public override class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { + public override class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { guard let moduleMolecule = model as? ModuleMoleculeModel, let moduleModel = delegateObject?.moleculeDelegate?.getModuleWithName(moduleMolecule.moduleName), let classType = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moduleModel) as? ModelMoleculeViewProtocol.Type, - let name = classType.nameForReuse(moduleModel, delegateObject) else { + let name = classType.nameForReuse(with: moduleModel, delegateObject) else { // Critical error return "moduleMolecule<>" } return name } - public override class func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { + public override class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { - guard let moduleName = (molecule as? ModuleMoleculeModel)?.moduleName, + guard let moduleName = (model as? ModuleMoleculeModel)?.moduleName, let _ = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else { if let errorObject = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess), code: CoreUIErrorCode.ErrorCodeModuleMolecule.rawValue, domain: ErrorDomainNative, location: String(describing: self)) { error?.pointee = errorObject diff --git a/MVMCoreUI/Molecules/MoleculeHeaderView.swift b/MVMCoreUI/Molecules/MoleculeHeaderView.swift index 5d58c675..3404afc3 100644 --- a/MVMCoreUI/Molecules/MoleculeHeaderView.swift +++ b/MVMCoreUI/Molecules/MoleculeHeaderView.swift @@ -37,11 +37,11 @@ public class MoleculeHeaderView: MoleculeContainer { } // MARK: - ModelMoleculeViewProtocol - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let headerModel = headerModel else { return } if let lineModel = headerModel.line { - line.setWithModel(lineModel, delegateObject, additionalData) + line.set(with: lineModel, delegateObject, additionalData) } } diff --git a/MVMCoreUI/Molecules/RadioButtonModel.swift b/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift similarity index 84% rename from MVMCoreUI/Molecules/RadioButtonModel.swift rename to MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift index bb70dec7..f20ac3b2 100644 --- a/MVMCoreUI/Molecules/RadioButtonModel.swift +++ b/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift @@ -9,18 +9,18 @@ import Foundation import UIKit -@objcMembers public class RadioButtonModel: NSObject { +@objcMembers public class RadioButtonSelectionHelper: NSObject { private var selectedRadioButton: RadioButton? private var fieldGroupName: String? - public static func setupForRadioButtonGroup(radioButton: RadioButton, formValidator: FormValidator?) -> RadioButtonModel { + public static func setupForRadioButtonGroup(radioButton: RadioButton, formValidator: FormValidator?) -> RadioButtonSelectionHelper { guard let groupName = radioButton.radioGroupName, let formValidator = formValidator else { - return RadioButtonModel() + return RadioButtonSelectionHelper() } - let radioButtonModel = formValidator.radioButtonsModelByGroup[groupName] ?? RadioButtonModel() + let radioButtonModel = formValidator.radioButtonsModelByGroup[groupName] ?? RadioButtonSelectionHelper() radioButtonModel.fieldGroupName = radioButton.formFieldGroupName() formValidator.radioButtonsModelByGroup[groupName] = radioButtonModel return radioButtonModel @@ -34,7 +34,7 @@ import UIKit } // MARK: - FormValidationFormFieldProtocol -extension RadioButtonModel: FormValidationFormFieldProtocol { +extension RadioButtonSelectionHelper: FormValidationFormFieldProtocol { public func formFieldGroupName() -> String? { return selectedRadioButton?.formFieldGroupName() ?? self.fieldGroupName } diff --git a/MVMCoreUI/Molecules/Scroller.swift b/MVMCoreUI/Molecules/Scroller.swift index 8ee77816..6184f3d0 100644 --- a/MVMCoreUI/Molecules/Scroller.swift +++ b/MVMCoreUI/Molecules/Scroller.swift @@ -29,10 +29,10 @@ import UIKit constraint.isActive = true } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { if let casteModel = model as? ScrollerModel { if view != nil { - (view as? ModelMoleculeViewProtocol)?.setWithModel(casteModel.molecule, delegateObject, additionalData) + (view as? ModelMoleculeViewProtocol)?.set(with: casteModel.molecule, delegateObject, additionalData) } else { if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(casteModel.molecule, delegateObject) { contentView.addSubview(molecule) @@ -41,6 +41,6 @@ import UIKit } } } - super.setWithModel(model, delegateObject, additionalData) + super.set(with: model, delegateObject, additionalData) } } diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift index e9d7d34e..49b08b44 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift @@ -8,16 +8,16 @@ import UIKit -@objcMembers open class EyebrowHeadlineBodyLink: Container { +@objcMembers open class EyebrowHeadlineBodyLink: View { //-------------------------------------------------- // MARK: - Outlets //-------------------------------------------------- - let stack = Stack(frame: .zero) - let eyebrow = Label.commonLabelB3(true) - let headline = Label.commonLabelB1(true) - let body = Label.commonLabelB2(true) - let link = Link() + public let stack = Stack(frame: .zero) + public let eyebrow = Label.commonLabelB3(true) + public let headline = Label.commonLabelB1(true) + public let body = Label.commonLabelB2(true) + public let link = Link() var casteModel: EyebrowHeadlineBodyLinkModel? { get { return model as? EyebrowHeadlineBodyLinkModel } @@ -29,10 +29,8 @@ import UIKit open override func setupView() { super.setupView() - stack.stackItems = [StackItem(andContain: eyebrow), - StackItem(andContain: headline), - StackItem(andContain: body), - StackItem(andContain: link)] + stack.setAndCreateModel(with: [eyebrow, headline, body, link]) + stack.stackModel?.spacing = 0 addSubview(stack) NSLayoutConstraint.constraintPinSubview(toSuperview: stack) } @@ -49,7 +47,6 @@ import UIKit open override func reset() { super.reset() stack.reset() - stack.stackModel?.spacing = 0 eyebrow.styleB3(true) headline.styleB1(true) body.styleB2(true) @@ -59,25 +56,23 @@ import UIKit // MARK: - ModelMoleculeViewProtocol //-------------------------------------------------- - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) - eyebrow.setWithModel(casteModel?.eyebrow, delegateObject, additionalData) - headline.setWithModel(casteModel?.headline, delegateObject, additionalData) - body.setWithModel(casteModel?.body, delegateObject, additionalData) - link.setWithModel(casteModel?.link, delegateObject, additionalData) + eyebrow.setOptional(with: casteModel?.eyebrow, delegateObject, additionalData) + headline.setOptional(with: casteModel?.headline, delegateObject, additionalData) + body.setOptional(with: casteModel?.body, delegateObject, additionalData) + link.setOptional(with: casteModel?.link, delegateObject, additionalData) - // Create a stack model to use for the internal stack. - let stackModel = StackModel(molecules: [StackItemModel(gone: !eyebrow.hasText), - StackItemModel(gone: !headline.hasText), - StackItemModel(gone: !body.hasText), - StackItemModel(gone: (link.titleLabel?.text?.count ?? 0) == 0)]) - stackModel.spacing = 0 - stack.model = stackModel + // 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() } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 65 } } diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index 2b3567d7..00ccaeeb 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -73,17 +73,17 @@ import Foundation } // MARK:- ModelMoleculeViewProtocol - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 320 } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? HeadlineBodyCaretLinkImageModel else { return } - headlineBody.setWithModel(model.headlineBody, delegateObject, additionalData) - caretButton.setWithModel(model.caretLink, delegateObject, additionalData) + headlineBody.set(with: model.headlineBody, delegateObject, additionalData) + caretButton.setOptional(with: model.caretLink, delegateObject, additionalData) caretButton.isHidden = model.caretLink == nil - backgroundImageView.setWithModel(model.image, delegateObject, additionalData) + backgroundImageView.set(with: model.image, delegateObject, additionalData) backgroundImageView.alignFillHorizontal() backgroundImageView.alignFillVertical() } diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBody.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBody.swift index b94adef0..ba2aa009 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBody.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBody.swift @@ -124,19 +124,19 @@ open class HeadlineBody: View { // MARK: - ModelMoleculeViewProtocol //-------------------------------------------------- - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 58 } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let headlineBodyModel = model as? HeadlineBodyModel else { return } style(with: headlineBodyModel.style) - headlineLabel.setWithModel(headlineBodyModel.headline, delegateObject, additionalData) - messageLabel.setWithModel(headlineBodyModel.body, delegateObject, additionalData) + headlineLabel.setOptional(with: headlineBodyModel.headline, delegateObject, additionalData) + messageLabel.setOptional(with: headlineBodyModel.body, delegateObject, additionalData) } //-------------------------------------------------- diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyButton.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyButton.swift index a0f22f34..90183e6e 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyButton.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyButton.swift @@ -108,15 +108,15 @@ import UIKit } // MARK:- ModelMoleculeViewProtocol - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 320 } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? HeadlineBodyButtonModel else { return } buttonHeadlinePadding = model.buttonHeadlinePadding - headlineBody.setWithModel(model.headlineBody, delegateObject, additionalData) - button.setWithModel(model.button, delegateObject, additionalData) + headlineBody.set(with: model.headlineBody, delegateObject, additionalData) + button.set(with: model.button, delegateObject, additionalData) } } diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyLink.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyLink.swift index 6009c7e0..e9bfabaa 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyLink.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyLink.swift @@ -67,14 +67,14 @@ import UIKit } // MARK:- ModelMoleculeViewProtocol - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? HeadlineBodyLinkModel else { return } - headlineBody.setWithModel(model.headlineBody, delegateObject, additionalData) - link.setWithModel(model.link, delegateObject, additionalData) + headlineBody.set(with: model.headlineBody, delegateObject, additionalData) + link.set(with: model.link, delegateObject, additionalData) } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 60 } } diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeStack.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeStack.swift index ac6613ea..48f39fa0 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeStack.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeStack.swift @@ -10,7 +10,7 @@ import UIKit // This class is only temporarily necessary. Eventually we will have initWithModel instad of just init for moleculeviews, which will remove this need. open class StringAndMoleculeStack: MoleculeStackView { - override func createStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + override open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { guard let model = stackModel else { return } for stackItemModel in model.molecules { guard let stringAndMoleculeModel = stackItemModel.molecule as? StringAndMoleculeModel, @@ -21,7 +21,7 @@ open class StringAndMoleculeStack: MoleculeStackView { } let view = StringAndMoleculeView(string: stringAndMoleculeModel.string, molecule: molecule) let stackItem = MoleculeStackItem(andContain: view) - stackItem.setWithModel(stackItemModel, delegateObject, nil) + stackItem.set(with: stackItemModel, delegateObject, nil) stackItems.append(stackItem) } } diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeView.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeView.swift index ffd23b0a..95392b8d 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeView.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeView.swift @@ -76,11 +76,11 @@ open class StringAndMoleculeView: View { (molecule as? MoleculeViewProtocol)?.reset?() } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) guard let model = model as? StringAndMoleculeModel else { return } label.text = model.string - molecule.setWithModel(model.molecule, delegateObject, additionalData) + molecule.set(with: model.molecule, delegateObject, additionalData) } func updateLeftViewWidthConstraint(_ percent: CGFloat) { diff --git a/MVMCoreUI/Organisms/Carousel.swift b/MVMCoreUI/Organisms/Carousel.swift index 7262e122..9e2422e6 100644 --- a/MVMCoreUI/Organisms/Carousel.swift +++ b/MVMCoreUI/Organisms/Carousel.swift @@ -83,8 +83,8 @@ open class Carousel: View { } // MARK: - MVMCoreUIMoleculeViewProtocol - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) guard let carouselModel = model as? CarouselModel else { return } collectionView.backgroundColor = backgroundColor collectionView.layer.borderColor = backgroundColor?.cgColor @@ -159,7 +159,7 @@ open class Carousel: View { /// Returns the (identifier, class) of the molecule for the given map. func getMoleculeInfo(with molecule: MoleculeModelProtocol, delegateObject: MVMCoreUIDelegateObject?) -> (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)? { guard let className = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(molecule) , - let moleculeName = (className as? ModelMoleculeViewProtocol.Type)?.nameForReuse(molecule, delegateObject) ?? molecule.moleculeName else { + let moleculeName = (className as? ModelMoleculeViewProtocol.Type)?.nameForReuse(with: molecule, delegateObject) ?? molecule.moleculeName else { return nil } return (moleculeName, className, molecule) @@ -275,7 +275,7 @@ extension Carousel: UICollectionViewDataSource { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: moleculeInfo.identifier, for: indexPath) if let protocolCell = cell as? MVMCoreUIMoleculeViewProtocol & ModelMoleculeViewProtocol { protocolCell.reset?() - protocolCell.setWithModel(moleculeInfo.molecule, nil, nil) + protocolCell.set(with: moleculeInfo.molecule, nil, nil) protocolCell.updateView(collectionView.bounds.width) } setAccessiblity(cell, index: indexPath.row) diff --git a/MVMCoreUI/Organisms/MoleculeStackView.swift b/MVMCoreUI/Organisms/MoleculeStackView.swift index d6f934a7..12d79dcd 100644 --- a/MVMCoreUI/Organisms/MoleculeStackView.swift +++ b/MVMCoreUI/Organisms/MoleculeStackView.swift @@ -9,7 +9,7 @@ import UIKit open class MoleculeStackView: Stack { - override var stackModel: MoleculeStackModel? { + open override var stackModel: MoleculeStackModel? { get { return model as? MoleculeStackModel } } @@ -33,7 +33,7 @@ open class MoleculeStackView: Stack { // MARK: - Adding to stack /// Creates all of the stackItems for the stackItemModels - override func createStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + override open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { guard let stackItemModels = stackModel?.molecules else { return } for model in stackItemModels { if let stackItem = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(model, delegateObject) as? MoleculeStackItem { diff --git a/MVMCoreUI/Organisms/Stack.swift b/MVMCoreUI/Organisms/Stack.swift index 602ab0f1..696964f1 100644 --- a/MVMCoreUI/Organisms/Stack.swift +++ b/MVMCoreUI/Organisms/Stack.swift @@ -9,22 +9,22 @@ import Foundation -open class Stack: Container where T: StackModelProtocol { +open class Stack: Container where T: (StackModelProtocol & MoleculeModelProtocol) { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - var contentView: UIView = MVMCoreUICommonViewsUtility.commonView() - var stackModel: T? { + open var contentView: UIView = MVMCoreUICommonViewsUtility.commonView() + open var stackModel: T? { get { return model as? T } } - var stackItems: [UIView] = [] + open var stackItems: [UIView] = [] //-------------------------------------------------- // MARK: - Helpers //-------------------------------------------------- - public func pinView(_ view: UIView, toView: UIView, attribute: NSLayoutConstraint.Attribute, relation: NSLayoutConstraint.Relation, priority: UILayoutPriority, constant: CGFloat) { + open func pinView(_ view: UIView, toView: UIView, attribute: NSLayoutConstraint.Attribute, relation: NSLayoutConstraint.Relation, priority: UILayoutPriority, constant: CGFloat) { let constraint = NSLayoutConstraint(item: view, attribute: attribute, relatedBy: relation, toItem: toView, attribute: attribute, multiplier: 1.0, constant: constant) constraint.priority = priority @@ -32,7 +32,7 @@ open class Stack: Container where T: StackModelProtocol { } /// Restacks the existing items. - func restack() { + open func restack() { removeAllItemViews() guard let stackModel = stackModel else { return } let stackItems = self.stackItems @@ -49,7 +49,7 @@ open class Stack: Container where T: StackModelProtocol { } /// Removes all stack items views from the view. - func removeAllItemViews() { + open func removeAllItemViews() { for item in stackItems { item.removeFromSuperview() } @@ -63,20 +63,52 @@ open class Stack: Container where T: StackModelProtocol { super.init(frame: frame) } - public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + /// The main initializer for model driven + public init(with model: T, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + super.init(frame: .zero) + setOptional(with: model, delegateObject, additionalData) + } + + /// The main initializer for hardcode driven + public init(with model: T, stackItems: [UIView]) { super.init(frame: CGRect.zero) - setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + self.model = model + self.stackItems = stackItems } public required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } + /// Returns a Stack created with a StackModel and StackItems containing the passed in views. + public static func createStack(with views: [UIView], axis: NSLayoutConstraint.Axis? = nil, spacing: CGFloat? = nil) -> Stack { + var items: [StackItem] = [] + var models: [StackItemModel] = [] + for view in views { + items.append(StackItem(andContain: view)) + models.append(StackItemModel()) + } + let model = StackModel(molecules: models, axis: axis, spacing: spacing) + return Stack(with: model, stackItems: items) + } + + /// Returns a Stack created with a StackModel containing the passed in views and using the passed in stackitems. + public static func createStack(with viewModels:[(view: UIView, model: StackItemModel)], axis: NSLayoutConstraint.Axis? = nil, spacing: CGFloat? = nil) -> Stack { + var stackItems: [StackItem] = [] + var models: [StackItemModel] = [] + for item in viewModels { + stackItems.append(StackItem(andContain: item.view)) + models.append(item.model) + } + let model = StackModel(molecules: models, axis: axis, spacing: spacing) + return Stack(with: model, stackItems: stackItems) + } + //-------------------------------------------------- // MARK: - MFViewProtocol //-------------------------------------------------- - public override func setupView() { + open override func setupView() { super.setupView() guard contentView.superview == nil else { return } MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0) @@ -88,7 +120,7 @@ open class Stack: Container where T: StackModelProtocol { contentView.setContentHuggingPriority(.defaultHigh, for: .horizontal) } - public override func updateView(_ size: CGFloat) { + open override func updateView(_ size: CGFloat) { super.updateView(size) for item in stackItems { (item as? MVMCoreViewProtocol)?.updateView(size) @@ -99,7 +131,7 @@ open class Stack: Container where T: StackModelProtocol { // MARK: - MVMCoreUIMoleculeViewProtocol //-------------------------------------------------- - public override func reset() { + open override func reset() { super.reset() backgroundColor = .clear for item in stackItems { @@ -107,13 +139,13 @@ open class Stack: Container where T: StackModelProtocol { } } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { let previousModel = self.model - super.setWithModel(model, delegateObject, additionalData) + super.set(with: model, delegateObject, additionalData) removeAllItemViews() // If the items in the stack are different, clear them, create new ones. - if (previousModel == nil) || Self.nameForReuse(previousModel, delegateObject) != Self.nameForReuse(model, delegateObject) { + if (previousModel == nil) || Self.nameForReuse(with: previousModel!, delegateObject) != Self.nameForReuse(with: model, delegateObject) { stackItems = [] createStackItemsFromModel(model, delegateObject, additionalData) } else { @@ -123,7 +155,7 @@ open class Stack: Container where T: StackModelProtocol { restack() } - public override class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { + open override class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { // This will aggregate names of molecules to make an id. guard let model = model as? T else { return "stack<>" @@ -132,7 +164,7 @@ open class Stack: Container where T: StackModelProtocol { for case let item in model.molecules { if let moleculeName = item.moleculeName { if let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping[moleculeName] as? ModelMoleculeViewProtocol.Type, - let nameForReuse = moleculeClass.nameForReuse(item, delegateObject) { + let nameForReuse = moleculeClass.nameForReuse(with: item, delegateObject) { name.append(nameForReuse + ",") } else { name.append(moleculeName + ",") @@ -144,14 +176,14 @@ open class Stack: Container where T: StackModelProtocol { } // Need to update to take into account first spacing flag - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - guard let model = molecule as? T else { return 0 } + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + guard let model = model as? T else { return 0 } let horizontal = model.axis == .horizontal var estimatedHeight: CGFloat = 0 for case let item in model.molecules { if item.gone { continue } - let height = (MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(item) as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(forRow: item, delegateObject: delegateObject) ?? 0 + let height = (MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(item) as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(with: item, delegateObject) ?? 0 if !horizontal { // Vertical stack aggregates the items let spacing = item.spacing ?? model.spacing @@ -164,11 +196,11 @@ open class Stack: Container where T: StackModelProtocol { return estimatedHeight } - public override class func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { - guard let model = molecule as? T else { return nil } + open override class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { + guard let model = model as? T else { return nil } var modules: [String] = [] for case let item in model.molecules { - if let modulesForMolecule = (MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(item) as? ModelMoleculeViewProtocol.Type)?.requiredModules(item, delegateObject: delegateObject, error: error) { + if let modulesForMolecule = (MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(item) as? ModelMoleculeViewProtocol.Type)?.requiredModules(with: item, delegateObject, error: error) { modules += modulesForMolecule } } @@ -180,19 +212,43 @@ open class Stack: Container where T: StackModelProtocol { //-------------------------------------------------- /// Can be subclassed to create views when we get stack item models and have no views yet - func createStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { } + open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { } /// Can be subclassed to set stack items with model when we already have views - func setStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + open func setStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let models = stackModel?.molecules else { return } for (index, element) in models.enumerated() { - (stackItems[index] as? ModelMoleculeViewProtocol)?.setWithModel(element, delegateObject, additionalData) + (stackItems[index] as? ModelMoleculeViewProtocol)?.set(with: element, delegateObject, additionalData) } } //-------------------------------------------------- // MARK: - Adding to stack //-------------------------------------------------- + /// Sets the stack with StackItems containing the passed in views and creates a StackModel with StackItems. + open func setAndCreateModel(with views: [UIView]) { + var stackItems: [StackItem] = [] + var models: [StackItemModel] = [] + for view in views { + stackItems.append(StackItem(andContain: view)) + models.append(StackItemModel()) + } + self.stackItems = stackItems + model = StackModel(molecules: models) + } + + /// Sets the stack with StackItems containing the passed in views and sets the StackModel with models. + open func set(with viewModels:[(view: UIView, model: T.AnyStackItemModel)]) { + guard var stackModel = self.stackModel else { return } + var stackItems: [StackItem] = [] + var models: [T.AnyStackItemModel] = [] + for item in viewModels { + stackItems.append(StackItem(andContain: item.view)) + models.append(item.model) + } + stackModel.molecules = models + self.stackItems = stackItems + } /// Gets the percent modifier. This value is used to help properly calculate percent for stack items when spacing is involved. private func getTotalSpace() -> CGFloat { @@ -237,7 +293,7 @@ open class Stack: Container where T: StackModelProtocol { if first { pinView(view, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: stackModel.useStackSpacingBeforeFirstItem ? spacing : model.spacing ?? 0) } else if let previousView = stackItems.last(where: { item in - return !model.gone + return item.superview != nil }) { view.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: spacing).isActive = true } @@ -256,7 +312,7 @@ open class Stack: Container where T: StackModelProtocol { // First horizontal item has no spacing by default unless told otherwise. pinView(view, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: stackModel.useStackSpacingBeforeFirstItem ? spacing : model.spacing ?? 0) } else if let previousView = stackItems.last(where: { item in - return !model.gone + return item.superview != nil }) { view.leftAnchor.constraint(equalTo: previousView.rightAnchor, constant: spacing).isActive = true } diff --git a/MVMCoreUI/Organisms/StackModel.swift b/MVMCoreUI/Organisms/StackModel.swift index b762a03c..46f68c3b 100644 --- a/MVMCoreUI/Organisms/StackModel.swift +++ b/MVMCoreUI/Organisms/StackModel.swift @@ -9,16 +9,23 @@ import Foundation @objcMembers public class StackModel: StackModelProtocol, MoleculeModelProtocol { + static let defaultSpacing: CGFloat = 16.0 + public static var identifier: String = "simpleStack" public var backgroundColor: Color? public var molecules: [StackItemModel] public var axis: NSLayoutConstraint.Axis = .vertical - public var spacing: CGFloat = 16.0 + public var spacing: CGFloat = StackModel.defaultSpacing public var useStackSpacingBeforeFirstItem = false - - public init(molecules: [StackItemModel], axis: NSLayoutConstraint.Axis = .vertical) { + + public init(molecules: [StackItemModel], axis: NSLayoutConstraint.Axis? = nil, spacing: CGFloat? = nil) { self.molecules = molecules - self.axis = axis + if let axis = axis { + self.axis = axis + } + if let spacing = spacing { + self.spacing = spacing + } } private enum CodingKeys: String, CodingKey { diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelExtension.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelExtension.swift index 6249e61e..8eb0c34d 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelExtension.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelExtension.swift @@ -10,7 +10,7 @@ import Foundation public extension MVMCoreUIMoleculeMappingObject { - func register(viewClass: V.Type, viewModelClass: M.Type) { + func register(viewClass: V.Type, viewModelClass: M.Type) { try? ModelRegistry.register(viewModelClass) MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(viewClass, forKey: viewModelClass.identifier as NSString) } @@ -34,7 +34,7 @@ public extension MVMCoreUIMoleculeMappingObject { let setData = {() in if let molecule = molecule as? ModelMoleculeViewProtocol { - molecule.setWithModel(model, delegateObject, nil) + molecule.set(with: model, delegateObject, nil) } else { molecule.setWithJSON?(model.toJSON(), delegateObject: delegateObject, additionalData: nil) } diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index 9075360c..003b5d03 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -29,6 +29,7 @@ import Foundation // Buttons MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TwoButtonView.self, viewModelClass: TwoButtonViewModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ExternalLink.self, viewModelClass: ExternalLinkModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Link.self, viewModelClass: LinkModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretLink.self, viewModelClass: CaretLinkModel.self) @@ -50,22 +51,19 @@ import Foundation MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CheckboxLabel.self, viewModelClass: CheckboxLabelModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Arrow.self, viewModelClass: ArrowModel.self) // Horizontal Combination Molecules MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListThreeColumnPlanDataDivider.self, viewModelClass: ListThreeColumnPlanDataDividerModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListOneColumnFullWidthTextAllTextAndLinks.self, viewModelClass: ListOneColumnFullWidthTextAllTextAndLinksModel.self) - - // Vertical Combination Molecules MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadLineBodyCaretLinkImage.self, viewModelClass: HeadlineBodyCaretLinkImageModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: EyebrowHeadlineBodyLink.self, viewModelClass: EyebrowHeadlineBodyLinkModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyLink.self, viewModelClass: HeadlineBodyLinkModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyButton.self, viewModelClass: HeadlineBodyButtonModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self) // Left Right Molecules MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CornerLabels.self, viewModelClass: CornerLabelsModel.self) @@ -74,9 +72,6 @@ import Foundation MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyToggle.self, viewModelClass: HeadlineBodyToggleModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyLinkToggle.self, viewModelClass: HeadlineBodyLinkToggleModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ActionDetailWithImage.self, viewModelClass: ActionDetailWithImageModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListLeftVariableIconWithRightCaret.self, viewModelClass: ListLeftVariableIconWithRightCaretModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListLeftVariableCheckboxAllTextAndLinks.self, viewModelClass: ListLeftVariableCheckboxAllTextAndLinksModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self) // List items MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeTableViewCell.self, viewModelClass: MoleculeListItemModel.self) @@ -103,12 +98,23 @@ import Foundation // Other Organisms MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Carousel.self, viewModelClass: CarouselModel.self) + // Designed List Items + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListLeftVariableIconWithRightCaret.self, viewModelClass: ListLeftVariableIconWithRightCaretModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListLeftVariableCheckboxAllTextAndLinks.self, viewModelClass: ListLeftVariableCheckboxAllTextAndLinksModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListLeftVariableRadioButtonAndPaymentMethod.self, viewModelClass: ListLeftVariableRadioButtonAndPaymentMethodModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListOneColumnFullWidthTextAllTextAndLinks.self, viewModelClass: ListOneColumnFullWidthTextAllTextAndLinksModel.self) + + // Designed Section Dividers + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListThreeColumnPlanDataDivider.self, viewModelClass: ListThreeColumnPlanDataDividerModel.self) + // TODO: Need model MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(DigitEntryField.self, forKey: "digitTextField" as NSString) MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(DateDropdownEntryField.self, forKey: "dateDropdownEntryField" as NSString) MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(Checkbox.self, forKey: "checkbox" as NSString) MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(CheckboxLabel.self, forKey: "checkboxLabel" as NSString) - MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(RadioButton.self, forKey: "radioButton" as NSString) MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(RadioButtonLabel.self, forKey: "radioButtonLabel" as NSString) MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(MVMCoreUIPageControl.self, forKey: "barsPager" as NSString) diff --git a/MVMCoreUI/Styles/MFStyler.h b/MVMCoreUI/Styles/MFStyler.h index bdef57ba..6accea28 100644 --- a/MVMCoreUI/Styles/MFStyler.h +++ b/MVMCoreUI/Styles/MFStyler.h @@ -98,6 +98,48 @@ B3 -> Legal //------------------------------------------------- // Returns the fonts for these styles. Scales them as needed by default + +#pragma mark - 3.0 fonts +///auto select corresponding font based on font size, DS for font bigger than 15 pt, TX for font smaller than 15 pt ++ (nonnull UIFont *)getMVA3FontSize:(CGFloat)size bold:(BOOL)isBold; +///Bold 36pt ++ (nonnull UIFont *)fontTitle2XLarge:(BOOL)genericScaling; ++ (nonnull UIFont *)fontTitle2XLarge; +///Bold 32pt ++ (nonnull UIFont *)fontTitleXLarge:(BOOL)genericScaling; ++ (nonnull UIFont *)fontTitleXLarge; +///Bold 24pt ++ (nonnull UIFont *)fontBoldTitleLarge:(BOOL)genericScaling; ++ (nonnull UIFont *)fontBoldTitleLarge; +///Regular 24pt ++ (nonnull UIFont *)fontRegularTitleLarge:(BOOL)genericScaling; ++ (nonnull UIFont *)fontRegularTitleLarge; +///Bold 20pt ++ (nonnull UIFont *)fontBoldTitleMedium:(BOOL)genericScaling; ++ (nonnull UIFont *)fontBoldTitleMedium; +///Regular 20pt ++ (nonnull UIFont *)fontRegularTitleMedium:(BOOL)genericScaling; ++ (nonnull UIFont *)fontRegularTitleMedium; +///Bold 16pt ++ (nonnull UIFont *)fontBoldBodyLarge:(BOOL)genericScaling; ++ (nonnull UIFont *)fontBoldBodyLarge; +///Regular 16pt ++ (nonnull UIFont *)fontRegularBodyLarge:(BOOL)genericScaling; ++ (nonnull UIFont *)fontRegularBodyLarge; +///Bold 13pt ++ (nonnull UIFont *)fontBoldBodySmall:(BOOL)genericScaling; ++ (nonnull UIFont *)fontBoldBodySmall; +///Regular 13pt ++ (nonnull UIFont *)fontRegularBodySmall:(BOOL)genericScaling; ++ (nonnull UIFont *)fontRegularBodySmall; +///Bold 11pt ++ (nonnull UIFont *)fontBoldMicro:(BOOL)genericScaling; ++ (nonnull UIFont *)fontBoldMicro; +///Regular 11pt ++ (nonnull UIFont *)fontRegularMicro:(BOOL)genericScaling; ++ (nonnull UIFont *)fontRegularMicro; + + #pragma mark - 2.0 fonts //75Bd 40pt @@ -206,9 +248,50 @@ B3 -> Legal //------------------------------------------------- // Applies the styles to the passed in objects. +#pragma mark - 3.0 Styles + ++ (void)styleLabelTitle2XLarge:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; ++ (void)styleLabelTitle2XLarge:(nonnull UILabel *)label; + ++ (void)styleLabelTitleXLarge:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; ++ (void)styleLabelTitleXLarge:(nonnull UILabel *)label; + ++ (void)styleLabelBoldTitleLarge:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; ++ (void)styleLabelBoldTitleLarge:(nonnull UILabel *)label; + ++ (void)styleLabelRegularTitleLarge:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; ++ (void)styleLabelRegularTitleLarge:(nonnull UILabel *)label; + ++ (void)styleLabelBoldTitleMedium:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; ++ (void)styleLabelBoldTitleMedium:(nonnull UILabel *)label; + ++ (void)styleLabelRegularTitleMedium:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; ++ (void)styleLabelRegularTitleMedium:(nonnull UILabel *)label; + ++ (void)styleLabelBoldBodyLarge:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; ++ (void)styleLabelBoldBodyLarge:(nonnull UILabel *)label; + ++ (void)styleLabelRegularBodyLarge:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; ++ (void)styleLabelRegularBodyLarge:(nonnull UILabel *)label; + ++ (void)styleLabelBoldBodySmall:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; ++ (void)styleLabelBoldBodySmall:(nonnull UILabel *)label; + ++ (void)styleLabelRegularBodySmall:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; ++ (void)styleLabelRegularBodySmall:(nonnull UILabel *)label; + ++ (void)styleLabelBoldMicro:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; ++ (void)styleLabelBoldMicro:(nonnull UILabel *)label; + ++ (void)styleLabelRegularMicro:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; ++ (void)styleLabelRegularMicro:(nonnull UILabel *)label; + +/// Will style the label with mva 3.0 fonts based on the string. ++ (BOOL)styleMVA3Label:(nonnull UILabel *)label withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling; + #pragma mark - 2.0 styles -/// Will style the label based on the string. Accepted values, H1, H2, H3, H32, B1, B2, B3, B20 +/// Will style the label based on the string. Accepted values, including mva3.0 fonts and 2.0 fonts H1, H2, H3, H32, B1, B2, B3, B20 + (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style; + (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling; @@ -257,6 +340,43 @@ B3 -> Legal #pragma mark - Attributed Strings ++ (nonnull NSAttributedString *)styleGetTitle2XLargeAttributedString:(nullable NSString *)string; ++ (nonnull NSAttributedString *)styleGetTitle2XLargeAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; + ++ (nonnull NSAttributedString *)styleGetTitleXLargeAttributedString:(nullable NSString *)string; ++ (nonnull NSAttributedString *)styleGetTitleXLargeAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; + ++ (nonnull NSAttributedString *)styleGetBoldTitleLargeAttributedString:(nullable NSString *)string; ++ (nonnull NSAttributedString *)styleGetBoldTitleLargeAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; + ++ (nonnull NSAttributedString *)styleGetRegularTitleLargeAttributedString:(nullable NSString *)string; ++ (nonnull NSAttributedString *)styleGetRegularTitleLargeAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; + ++ (nonnull NSAttributedString *)styleGetBoldTitleMediumAttributedString:(nullable NSString *)string; ++ (nonnull NSAttributedString *)styleGetBoldTitleMediumAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; + ++ (nonnull NSAttributedString *)styleGetRegularTitleMediumAttributedString:(nullable NSString *)string; ++ (nonnull NSAttributedString *)styleGetRegularTitleMediumAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; + ++ (nonnull NSAttributedString *)styleGetBoldBodyLargeAttributedString:(nullable NSString *)string; ++ (nonnull NSAttributedString *)styleGetBoldBodyLargeAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; + ++ (nonnull NSAttributedString *)styleGetRegularBodyLargeAttributedString:(nullable NSString *)string; ++ (nonnull NSAttributedString *)styleGetRegularBodyLargeAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; + ++ (nonnull NSAttributedString *)styleGetBoldBodySmallAttributedString:(nullable NSString *)string; ++ (nonnull NSAttributedString *)styleGetBoldBodySmallAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; + ++ (nonnull NSAttributedString *)styleGetRegularBodySmallAttributedString:(nullable NSString *)string; ++ (nonnull NSAttributedString *)styleGetRegularBodySmallAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; + ++ (nonnull NSAttributedString *)styleGetBoldMicroAttributedString:(nullable NSString *)string; ++ (nonnull NSAttributedString *)styleGetBoldMicroAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; + ++ (nonnull NSAttributedString *)styleGetRegularMicroAttributedString:(nullable NSString *)string; ++ (nonnull NSAttributedString *)styleGetRegularMicroAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling; + + /// Will style the string based on the string. Accepted values, H1, H2, H3, H32, B1, B2, B3, B20 + (nonnull NSAttributedString *)styleGetAttributedString:(nullable NSString *)string withStyle:(nullable NSString *)style; + (nonnull NSAttributedString *)styleGetAttributedString:(nullable NSString *)string withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling; diff --git a/MVMCoreUI/Styles/MFStyler.m b/MVMCoreUI/Styles/MFStyler.m index c3dc8946..213c205e 100644 --- a/MVMCoreUI/Styles/MFStyler.m +++ b/MVMCoreUI/Styles/MFStyler.m @@ -111,6 +111,168 @@ CGFloat const LabelWithInternalButtonLineSpace = 2; }]; } +#pragma mark - 3.0 fonts + ++ (nonnull UIFont *)getMVA3FontSize:(CGFloat)size bold:(BOOL)isBold { + if (isBold) { + if (size >= 15) { + return [MFFonts mfFontDSBold:size]; + } else { + return [MFFonts mfFontTXBold:size]; + } + } else { + if (size >= 15) { + return [MFFonts mfFontDSRegular:size]; + } else { + return [MFFonts mfFontTXRegular:size]; + } + } +} + ++ (nonnull UIFont *)fontTitle2XLarge:(BOOL)genericScaling { + CGFloat size = 36; + if (genericScaling) { + size = [self sizeFontGenericForCurrentDevice:size]; + } + return [self getMVA3FontSize:size bold:YES]; +} + ++ (nonnull UIFont *)fontTitle2XLarge { + return [self fontTitle2XLarge:YES]; +} + ++ (nonnull UIFont *)fontTitleXLarge:(BOOL)genericScaling { + CGFloat size = 32; + if (genericScaling) { + size = [self sizeFontGenericForCurrentDevice:size]; + } + return [self getMVA3FontSize:size bold:YES]; +} ++ (nonnull UIFont *)fontTitleXLarge{ + return [self fontTitleXLarge:YES]; +} + ++ (nonnull UIFont *)fontBoldTitleLarge:(BOOL)genericScaling { + CGFloat size = 24; + if (genericScaling) { + size = [self sizeFontGenericForCurrentDevice:size]; + } + return [self getMVA3FontSize:size bold:YES]; +} + ++ (nonnull UIFont *)fontBoldTitleLarge { + return [self fontBoldTitleLarge:YES]; +} + ++ (nonnull UIFont *)fontRegularTitleLarge:(BOOL)genericScaling { + CGFloat size = 24; + if (genericScaling) { + size = [self sizeFontGenericForCurrentDevice:size]; + } + return [self getMVA3FontSize:size bold:NO]; +} + ++ (nonnull UIFont *)fontRegularTitleLarge { + return [self fontRegularTitleLarge:YES]; +} + ++ (nonnull UIFont *)fontBoldTitleMedium:(BOOL)genericScaling { + CGFloat size = 20; + if (genericScaling) { + size = [self sizeFontGenericForCurrentDevice:size]; + } + return [self getMVA3FontSize:size bold:YES]; +} + ++ (nonnull UIFont *)fontBoldTitleMedium { + return [self fontBoldTitleMedium:YES]; +} + ++ (nonnull UIFont *)fontRegularTitleMedium:(BOOL)genericScaling { + CGFloat size = 20; + if (genericScaling) { + size = [self sizeFontGenericForCurrentDevice:size]; + } + return [self getMVA3FontSize:size bold:NO]; +} + ++ (nonnull UIFont *)fontRegularTitleMedium { + return [self fontRegularTitleMedium:YES]; +} + ++ (nonnull UIFont *)fontBoldBodyLarge:(BOOL)genericScaling { + CGFloat size = 16; + if (genericScaling) { + size = [self sizeFontGenericForCurrentDevice:size]; + } + return [self getMVA3FontSize:size bold:YES]; +} + ++ (nonnull UIFont *)fontBoldBodyLarge { + return [self fontBoldBodyLarge:YES]; +} + ++ (nonnull UIFont *)fontRegularBodyLarge:(BOOL)genericScaling { + CGFloat size = 16; + if (genericScaling) { + size = [self sizeFontGenericForCurrentDevice:size]; + } + return [self getMVA3FontSize:size bold:NO]; +} + ++ (nonnull UIFont *)fontRegularBodyLarge { + return [self fontRegularBodyLarge:YES]; +} + ++ (nonnull UIFont *)fontBoldBodySmall:(BOOL)genericScaling { + CGFloat size = 13; + if (genericScaling) { + size = [self sizeFontGenericForCurrentDevice:size]; + } + return [self getMVA3FontSize:size bold:YES]; +} + ++ (nonnull UIFont *)fontBoldBodySmall { + return [self fontBoldBodySmall:YES]; +} + ++ (nonnull UIFont *)fontRegularBodySmall:(BOOL)genericScaling { + CGFloat size = 13; + if (genericScaling) { + size = [self sizeFontGenericForCurrentDevice:size]; + } + return [self getMVA3FontSize:size bold:NO]; +} + ++ (nonnull UIFont *)fontRegularBodySmall { + return [self fontRegularBodySmall:YES]; +} + ++ (nonnull UIFont *)fontBoldMicro:(BOOL)genericScaling { + CGFloat size = 11; + if (genericScaling) { + size = [self sizeFontGenericForCurrentDevice:size]; + } + return [self getMVA3FontSize:size bold:YES]; +} + ++ (nonnull UIFont *)fontBoldMicro { + return [self fontBoldMicro:YES]; +} + ++ (nonnull UIFont *)fontRegularMicro:(BOOL)genericScaling { + CGFloat size = 11; + if (genericScaling) { + size = [self sizeFontGenericForCurrentDevice:size]; + } + return [self getMVA3FontSize:size bold:NO]; +} + ++ (nonnull UIFont *)fontRegularMicro { + return [self fontRegularMicro:YES]; +} + + #pragma mark - 2.0 fonts + (nullable UIFont *)fontH1:(BOOL)genericScaling { @@ -514,10 +676,165 @@ CGFloat const LabelWithInternalButtonLineSpace = 2; return [MFFonts mfFont55Rg:[self sizeFontGenericForCurrentDevice:size]]; } +#pragma mark - 3.0 Styles + ++ (void)styleLabelTitle2XLarge:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling { + label.font = [MFStyler fontTitle2XLarge:genericScaling]; + label.textColor = [UIColor blackColor]; +} + ++ (void)styleLabelTitle2XLarge:(nonnull UILabel *)label { + [self styleLabelTitle2XLarge:label genericScaling:YES]; +} + ++ (void)styleLabelTitleXLarge:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling { + label.font = [MFStyler fontTitleXLarge:genericScaling]; + label.textColor = [UIColor blackColor]; +} + ++ (void)styleLabelTitleXLarge:(nonnull UILabel *)label { + [self styleLabelTitleXLarge:label genericScaling:YES]; +} + ++ (void)styleLabelBoldTitleLarge:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling { + label.font = [MFStyler fontBoldTitleLarge:genericScaling]; + label.textColor = [UIColor blackColor]; +} + ++ (void)styleLabelBoldTitleLarge:(nonnull UILabel *)label { + [self styleLabelBoldTitleLarge:label genericScaling:YES]; +} + ++ (void)styleLabelRegularTitleLarge:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling { + label.font = [MFStyler fontRegularTitleLarge:genericScaling]; + label.textColor = [UIColor blackColor]; +} + ++ (void)styleLabelRegularTitleLarge:(nonnull UILabel *)label { + [self styleLabelBoldTitleLarge:label genericScaling:YES]; +} + ++ (void)styleLabelBoldTitleMedium:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling { + label.font = [MFStyler fontBoldTitleMedium:genericScaling]; + label.textColor = [UIColor blackColor]; +} + ++ (void)styleLabelBoldTitleMedium:(nonnull UILabel *)label { + [self styleLabelBoldTitleMedium:label genericScaling:YES]; +} + ++ (void)styleLabelRegularTitleMedium:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling { + label.font = [MFStyler fontRegularTitleMedium:genericScaling]; + label.textColor = [UIColor blackColor]; +} + ++ (void)styleLabelRegularTitleMedium:(nonnull UILabel *)label { + [self styleLabelRegularTitleMedium:label genericScaling:YES]; +} + ++ (void)styleLabelBoldBodyLarge:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling { + label.font = [MFStyler fontBoldBodyLarge:genericScaling]; + label.textColor = [UIColor blackColor]; +} + ++ (void)styleLabelBoldBodyLarge:(nonnull UILabel *)label { + [self styleLabelBoldBodyLarge:label genericScaling:YES]; +} + ++ (void)styleLabelRegularBodyLarge:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling { + label.font = [MFStyler fontRegularBodyLarge:genericScaling]; + label.textColor = [UIColor blackColor]; +} + ++ (void)styleLabelRegularBodyLarge:(nonnull UILabel *)label { + [self styleLabelRegularBodyLarge:label genericScaling:YES]; +} + ++ (void)styleLabelBoldBodySmall:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling { + label.font = [MFStyler fontBoldBodySmall:genericScaling]; + label.textColor = [UIColor blackColor]; +} + ++ (void)styleLabelBoldBodySmall:(nonnull UILabel *)label { + [self styleLabelBoldBodySmall:label genericScaling:YES]; +} + ++ (void)styleLabelRegularBodySmall:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling { + label.font = [MFStyler fontRegularBodySmall:genericScaling]; + label.textColor = [UIColor blackColor]; +} + ++ (void)styleLabelRegularBodySmall:(nonnull UILabel *)label { + [self styleLabelRegularBodySmall:label genericScaling:YES]; +} + ++ (void)styleLabelBoldMicro:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling { + label.font = [MFStyler fontBoldMicro:genericScaling]; + label.textColor = [UIColor blackColor]; +} + ++ (void)styleLabelBoldMicro:(nonnull UILabel *)label { + [self styleLabelBoldMicro:label genericScaling:YES]; +} + ++ (void)styleLabelRegularMicro:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling { + label.font = [MFStyler fontRegularMicro:genericScaling]; + label.textColor = [UIColor blackColor]; +} + ++ (void)styleLabelRegularMicro:(nonnull UILabel *)label { + [self styleLabelRegularMicro:label genericScaling:YES]; +} + ++ (BOOL)styleMVA3Label:(nonnull UILabel *)label withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling { + if ([style isEqualToString:@"Title2XLarge"]) { + [self styleLabelTitle2XLarge:label genericScaling:genericScaling]; + return YES; + } else if ([style isEqualToString:@"TitleXLarge"]) { + [self styleLabelTitleXLarge:label genericScaling:genericScaling]; + return YES; + } else if ([style isEqualToString:@"BoldTitleLarge"]) { + [self styleLabelBoldTitleLarge:label genericScaling:genericScaling]; + return YES; + } else if ([style isEqualToString:@"RegularTitleLarge"]) { + [self styleLabelRegularTitleLarge:label genericScaling:genericScaling]; + return YES; + } else if ([style isEqualToString:@"BoldTitleMedium"]) { + [self styleLabelBoldTitleMedium:label genericScaling:genericScaling]; + return YES; + } else if ([style isEqualToString:@"RegularTitleMedium"]) { + [self styleLabelRegularTitleMedium:label genericScaling:genericScaling]; + return YES; + } else if ([style isEqualToString:@"BoldBodyLarge"]) { + [self styleLabelBoldBodyLarge:label genericScaling:genericScaling]; + return YES; + } else if ([style isEqualToString:@"RegularBodyLarge"]) { + [self styleLabelRegularBodyLarge:label genericScaling:genericScaling]; + return YES; + } else if ([style isEqualToString:@"BoldBodySmall"]) { + [self styleLabelBoldBodySmall:label genericScaling:genericScaling]; + return YES; + } else if ([style isEqualToString:@"RegularBodySmall"]) { + [self styleLabelRegularBodySmall:label genericScaling:genericScaling]; + return YES; + } else if ([style isEqualToString:@"BoldMicro"]) { + [self styleLabelBoldMicro:label genericScaling:genericScaling]; + return YES; + } else if ([style isEqualToString:@"RegularMicro"]) { + [self styleLabelRegularMicro:label genericScaling:genericScaling]; + return YES; + } else { + return NO; + } +} + + #pragma mark - 2.0 Styles + (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling { - if ([style isEqualToString:@"H1"]) { + if ([self styleMVA3Label:label withStyle:style genericScaling:genericScaling]) { + //try mva 3.0 font first + } else if ([style isEqualToString:@"H1"]) { [self styleLabelH1:label genericScaling:genericScaling]; } else if ([style isEqualToString:@"H2"]) { [self styleLabelH2:label genericScaling:genericScaling]; @@ -697,6 +1014,105 @@ CGFloat const LabelWithInternalButtonLineSpace = 2; return attributedString; } + ++ (nonnull NSAttributedString *)styleGetTitle2XLargeAttributedString:(nullable NSString *)string { + return [MFStyler styleGetTitle2XLargeAttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetTitle2XLargeAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontTitle2XLarge:genericScaling] color:[UIColor blackColor]]; +} + ++ (nonnull NSAttributedString *)styleGetTitleXLargeAttributedString:(nullable NSString *)string { + return [MFStyler styleGetTitleXLargeAttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetTitleXLargeAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontTitleXLarge:genericScaling] color:[UIColor blackColor]]; +} + ++ (nonnull NSAttributedString *)styleGetBoldTitleLargeAttributedString:(nullable NSString *)string { + return [MFStyler styleGetBoldTitleLargeAttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetBoldTitleLargeAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontBoldTitleLarge:genericScaling] color:[UIColor blackColor]]; +} + ++ (nonnull NSAttributedString *)styleGetRegularTitleLargeAttributedString:(nullable NSString *)string { + return [MFStyler styleGetRegularTitleLargeAttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetRegularTitleLargeAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontRegularTitleLarge:genericScaling] color:[UIColor blackColor]]; +} + ++ (nonnull NSAttributedString *)styleGetBoldTitleMediumAttributedString:(nullable NSString *)string { + return [MFStyler styleGetBoldTitleMediumAttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetBoldTitleMediumAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontBoldTitleMedium:genericScaling] color:[UIColor blackColor]]; +} + ++ (nonnull NSAttributedString *)styleGetRegularTitleMediumAttributedString:(nullable NSString *)string { + return [MFStyler styleGetRegularTitleMediumAttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetRegularTitleMediumAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontRegularTitleMedium:genericScaling] color:[UIColor blackColor]]; +} + ++ (nonnull NSAttributedString *)styleGetBoldBodyLargeAttributedString:(nullable NSString *)string { + return [MFStyler styleGetBoldBodyLargeAttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetBoldBodyLargeAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontBoldBodyLarge:genericScaling] color:[UIColor blackColor]]; +} + ++ (nonnull NSAttributedString *)styleGetRegularBodyLargeAttributedString:(nullable NSString *)string { + return [MFStyler styleGetRegularBodyLargeAttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetRegularBodyLargeAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontRegularBodyLarge:genericScaling] color:[UIColor blackColor]]; +} + ++ (nonnull NSAttributedString *)styleGetBoldBodySmallAttributedString:(nullable NSString *)string { + return [MFStyler styleGetBoldBodySmallAttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetBoldBodySmallAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontBoldBodySmall:genericScaling] color:[UIColor blackColor]]; +} + ++ (nonnull NSAttributedString *)styleGetRegularBodySmallAttributedString:(nullable NSString *)string { + return [MFStyler styleGetRegularBodySmallAttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetRegularBodySmallAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontRegularBodySmall:genericScaling] color:[UIColor blackColor]]; +} + ++ (nonnull NSAttributedString *)styleGetBoldMicroAttributedString:(nullable NSString *)string { + return [MFStyler styleGetBoldMicroAttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetBoldMicroAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontBoldMicro:genericScaling] color:[UIColor blackColor]]; +} + ++ (nonnull NSAttributedString *)styleGetRegularMicroAttributedString:(nullable NSString *)string { + return [MFStyler styleGetRegularBodySmallAttributedString:string genericScaling:YES]; +} + ++ (nonnull NSAttributedString *)styleGetRegularMicroAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling { + return [MFStyler styleGetAttributedString:string font:[MFStyler fontRegularMicro:genericScaling] color:[UIColor blackColor]]; +} + + +//2.0 font get attributedString + (nonnull NSAttributedString *)styleGetH1AttributedString:(nullable NSString *)string { return [MFStyler styleGetH1AttributedString:string genericScaling:YES]; } diff --git a/MVMCoreUI/SupportingFiles/Fonts/NHaasGroteskDSStd-45Lt.otf b/MVMCoreUI/SupportingFiles/Fonts/NHaasGroteskDSStd-45Lt.otf deleted file mode 100644 index bddef9eb..00000000 Binary files a/MVMCoreUI/SupportingFiles/Fonts/NHaasGroteskDSStd-45Lt.otf and /dev/null differ diff --git a/MVMCoreUI/SupportingFiles/Fonts/NHaasGroteskDSStd-55Rg.otf b/MVMCoreUI/SupportingFiles/Fonts/NHaasGroteskDSStd-55Rg.otf deleted file mode 100644 index f56ed7aa..00000000 Binary files a/MVMCoreUI/SupportingFiles/Fonts/NHaasGroteskDSStd-55Rg.otf and /dev/null differ diff --git a/MVMCoreUI/SupportingFiles/Fonts/NHaasGroteskDSStd-75Bd.otf b/MVMCoreUI/SupportingFiles/Fonts/NHaasGroteskDSStd-75Bd.otf deleted file mode 100644 index fbcba354..00000000 Binary files a/MVMCoreUI/SupportingFiles/Fonts/NHaasGroteskDSStd-75Bd.otf and /dev/null differ diff --git a/MVMCoreUI/SupportingFiles/Fonts/VerizonNHGeDS-Bold.otf b/MVMCoreUI/SupportingFiles/Fonts/VerizonNHGeDS-Bold.otf new file mode 100755 index 00000000..dd3476af Binary files /dev/null and b/MVMCoreUI/SupportingFiles/Fonts/VerizonNHGeDS-Bold.otf differ diff --git a/MVMCoreUI/SupportingFiles/Fonts/VerizonNHGeDS-Regular.otf b/MVMCoreUI/SupportingFiles/Fonts/VerizonNHGeDS-Regular.otf new file mode 100755 index 00000000..ce34c596 Binary files /dev/null and b/MVMCoreUI/SupportingFiles/Fonts/VerizonNHGeDS-Regular.otf differ diff --git a/MVMCoreUI/SupportingFiles/Fonts/VerizonNHGeTX-Bold.otf b/MVMCoreUI/SupportingFiles/Fonts/VerizonNHGeTX-Bold.otf new file mode 100755 index 00000000..59b1f438 Binary files /dev/null and b/MVMCoreUI/SupportingFiles/Fonts/VerizonNHGeTX-Bold.otf differ diff --git a/MVMCoreUI/SupportingFiles/Fonts/VerizonNHGeTX-Regular.otf b/MVMCoreUI/SupportingFiles/Fonts/VerizonNHGeTX-Regular.otf new file mode 100755 index 00000000..13d202d1 Binary files /dev/null and b/MVMCoreUI/SupportingFiles/Fonts/VerizonNHGeTX-Regular.otf differ diff --git a/MVMCoreUI/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Templates/MoleculeListTemplate.swift index 9741f110..33d6beb0 100644 --- a/MVMCoreUI/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeListTemplate.swift @@ -106,7 +106,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { guard let moleculeInfo = moleculesInfo?[indexPath.row], - let estimatedHeight = (moleculeInfo.class as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(forRow: moleculeInfo.molecule, delegateObject: delegateObject() as? MVMCoreUIDelegateObject) + let estimatedHeight = (moleculeInfo.class as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(with: moleculeInfo.molecule, delegateObject() as? MVMCoreUIDelegateObject) else { return 0 } return estimatedHeight @@ -130,7 +130,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol protocolCell.setLines(with: templateModel?.line, delegateObject: delegate, additionalData: nil, indexPath: indexPath) } - (moleculeCell as? ModelMoleculeViewProtocol)?.setWithModel(moleculeInfo.molecule, delegate, nil) + (moleculeCell as? ModelMoleculeViewProtocol)?.set(with: moleculeInfo.molecule, delegate, nil) moleculeCell?.updateView(tableView.bounds.width) return cell @@ -283,7 +283,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol guard let listItem = listItem, let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(listItem), - let moleculeName = (moleculeClass as? ModelMoleculeViewProtocol.Type)?.nameForReuse(listItem, delegateObject() as? MVMCoreUIDelegateObject) ?? listItem.moleculeName + let moleculeName = (moleculeClass as? ModelMoleculeViewProtocol.Type)?.nameForReuse(with: listItem, delegateObject() as? MVMCoreUIDelegateObject) ?? listItem.moleculeName else { return nil } return (moleculeName, moleculeClass, listItem) diff --git a/MVMCoreUI/Templates/MoleculeStackTemplate.swift b/MVMCoreUI/Templates/MoleculeStackTemplate.swift index ef7a470d..e05a067a 100644 --- a/MVMCoreUI/Templates/MoleculeStackTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeStackTemplate.swift @@ -55,7 +55,7 @@ open class MoleculeStackTemplate: ThreeLayerViewController, TemplateProtocol { let stack = MoleculeStackView(frame: .zero) moleculeStackModel.useStackSpacingBeforeFirstItem = true moleculeStackModel.useHorizontalMargins = true - stack.setWithModel(moleculeStackModel, delegateObject() as? MVMCoreUIDelegateObject, nil) + stack.set(with: moleculeStackModel, delegateObject() as? MVMCoreUIDelegateObject, nil) return stack } diff --git a/MVMCoreUI/Utility/MFFonts.h b/MVMCoreUI/Utility/MFFonts.h index 484e2c82..46947581 100644 --- a/MVMCoreUI/Utility/MFFonts.h +++ b/MVMCoreUI/Utility/MFFonts.h @@ -10,11 +10,24 @@ #import #import +extern NSString * _Nonnull const DSBold; +extern NSString * _Nonnull const DSRegular; +extern NSString * _Nonnull const TXBold; +extern NSString * _Nonnull const TXRegular; + @interface MFFonts : NSObject -+ (nullable UIFont *)mfFont75Bd:(CGFloat)size; -+ (nullable UIFont *)mfFont55Rg:(CGFloat)size; +//mva 3.0 font, should use MFStyler.getMVA3FontSize:bold: instead, in most case. ++ (nonnull UIFont *)mfFontDSBold:(CGFloat)size; ++ (nonnull UIFont *)mfFontDSRegular:(CGFloat)size; ++ (nonnull UIFont *)mfFontTXBold:(CGFloat)size; ++ (nonnull UIFont *)mfFontTXRegular:(CGFloat)size; + +///return mfFontTXBold when size smaller than 15, otherwise, return mfFontDSBold ++ (nonnull UIFont *)mfFont75Bd:(CGFloat)size; +///return mfFontTXRegular when size smaller than 15, otherwise, return mfFontDSRegular ++ (nonnull UIFont *)mfFont55Rg:(CGFloat)size; + (nullable UIFont *)mfFontOcratxt:(CGFloat)size; -+ (nullable UIFont *)mfFontWithName:(nonnull NSString *)name size:(CGFloat)size; ++ (nonnull UIFont *)mfFontWithName:(nonnull NSString *)name size:(CGFloat)size; @end diff --git a/MVMCoreUI/Utility/MFFonts.m b/MVMCoreUI/Utility/MFFonts.m index 65326e6c..0a73fb36 100644 --- a/MVMCoreUI/Utility/MFFonts.m +++ b/MVMCoreUI/Utility/MFFonts.m @@ -10,14 +10,23 @@ #import #import "MVMCoreUIUtility.h" @import MVMCore.MVMCoreLoggingHandler; +@import MVMCore.MVMCoreErrorConstants; + +NSString * const DSBold = @"VerizonNHGeDS-Bold"; +NSString * const DSRegular = @"VerizonNHGeDS-Regular"; +NSString * const TXBold = @"VerizonNHGeTX-Bold"; +NSString * const TXRegular = @"VerizonNHGeTX-Regular"; + @implementation MFFonts + (void)loadMVMFonts { static dispatch_once_t once; dispatch_once(&once, ^{ - [MFFonts loadFont:@"NHaasGroteskDSStd-75Bd" type:@"otf"]; - [MFFonts loadFont:@"NHaasGroteskDSStd-55Rg" type:@"otf"]; + [MFFonts loadFont:DSBold type:@"otf"]; + [MFFonts loadFont:DSRegular type:@"otf"]; + [MFFonts loadFont:TXBold type:@"otf"]; + [MFFonts loadFont:TXRegular type:@"otf"]; [MFFonts loadFont:@"OCRAExtended" type:@"ttf"]; }); } @@ -39,23 +48,70 @@ CFRelease(provider); } -+ (nullable UIFont *)mfFont75Bd:(CGFloat)size { - [self loadMVMFonts]; - return [UIFont fontWithName:@"NHaasGroteskDSStd-75Bd" size:size]; ++ (nonnull UIFont *)mfFontDSBold:(CGFloat)size { + UIFont *font = [UIFont fontWithName:DSBold size:size]; + [self validFont:font fontName:DSBold]; + return font ?: [UIFont boldSystemFontOfSize:size]; } -+ (nullable UIFont *)mfFont55Rg:(CGFloat)size { ++ (nonnull UIFont *)mfFontDSRegular:(CGFloat)size { + UIFont *font = [UIFont fontWithName:DSRegular size:size]; + [self validFont:font fontName:DSRegular]; + return font ?: [UIFont systemFontOfSize:size]; +} + ++ (nonnull UIFont *)mfFontTXBold:(CGFloat)size { + UIFont *font = [UIFont fontWithName:TXBold size:size]; + [self validFont:font fontName:TXBold]; + return font ?: [UIFont boldSystemFontOfSize:size]; +} + ++ (nonnull UIFont *)mfFontTXRegular:(CGFloat)size { + UIFont *font = [UIFont fontWithName:TXRegular size:size]; + [self validFont:font fontName:TXRegular]; + return font ?: [UIFont systemFontOfSize:size]; +} + + ++ (UIFont *)mfFont75Bd:(CGFloat)size { [self loadMVMFonts]; - return [UIFont fontWithName:@"NHaasGroteskDSStd-55Rg" size:size]; + UIFont *font; + if (size >= 15) { + font = [self mfFontDSBold:size]; + } else { + font = [self mfFontTXBold:size]; + } + return font; +} + ++ (UIFont *)mfFont55Rg:(CGFloat)size { + [self loadMVMFonts]; + UIFont *font; + if (size >= 15) { + font = [self mfFontDSRegular:size]; + } else { + font = [self mfFontTXRegular:size]; + } + return font; } + (nullable UIFont *)mfFontOcratxt:(CGFloat)size { [self loadMVMFonts]; - return [UIFont fontWithName:@"OCRAExtended" size:size]; + UIFont *font = [UIFont fontWithName:@"OCRAExtended" size:size]; + [self validFont:font fontName:@"OCRAExtended"]; + return font; } -+ (nullable UIFont *)mfFontWithName:(nonnull NSString *)name size:(CGFloat)size { - return [UIFont fontWithName:name size:size] ?: [self mfFont55Rg:size]; ++ (UIFont *)mfFontWithName:(nonnull NSString *)name size:(CGFloat)size { + UIFont *font = [UIFont fontWithName:name size:size]; + [self validFont:font fontName:name]; + return font ?: [self mfFont55Rg:size]; } ++ (void)validFont:(UIFont *)font fontName:(NSString *)fontName { + if (font == nil) { + MVMCoreErrorObject *errorObject = [[MVMCoreErrorObject alloc] initWithTitle:@"font can not load" message:[NSString stringWithFormat:@"missing font name is %@", fontName] code:ErrorCodeFontNotFound domain:ErrorDomainNative location:@"MFStyler"]; + [MVMCoreLoggingHandler addErrorToLog:errorObject]; + } +} @end diff --git a/MVMCoreUI/Utility/UIFont+FontWrapping.h b/MVMCoreUI/Utility/UIFont+FontWrapping.h new file mode 100644 index 00000000..0302e25e --- /dev/null +++ b/MVMCoreUI/Utility/UIFont+FontWrapping.h @@ -0,0 +1,20 @@ +// +// UIFont+FontWrapping.h +// MVMCoreUI +// +// Created by Ryan on 2/26/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UIFont (FontWrapping) + +///if using mva3.0 font, should call this method to update font size. When size is bigger than 15 pt, using DS font family. Otherwise using TX font family +- (UIFont *)updateFontSize:(CGFloat)size; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MVMCoreUI/Utility/UIFont+FontWrapping.m b/MVMCoreUI/Utility/UIFont+FontWrapping.m new file mode 100644 index 00000000..8eedbb01 --- /dev/null +++ b/MVMCoreUI/Utility/UIFont+FontWrapping.m @@ -0,0 +1,26 @@ +// +// UIFont+FontWrapping.m +// MVMCoreUI +// +// Created by Ryan on 2/26/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +#import "UIFont+FontWrapping.h" +#import "MFFonts.h" +#import "MFStyler.h" +#import + +@implementation UIFont (FontWrapping) + +- (UIFont *)updateFontSize:(CGFloat)size { + if ([self.familyName isEqualToString:@"Verizon NHG eDS"]) { + return [MFStyler getMVA3FontSize:size bold:[self.fontName isEqualToString:DSBold]]; + } else if ([self.familyName isEqualToString:@"Verizon NHG eTX"]) { + return [MFStyler getMVA3FontSize:size bold:[self.fontName isEqualToString:TXBold]]; + } else { + return [self fontWithSize:size]; + } +} + +@end