diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 59816653..7cd0c44e 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -68,6 +68,8 @@ 0A21DB83235DFBC500C160A2 /* MdnEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A21DB82235DFBC500C160A2 /* MdnEntryField.swift */; }; 0A21DB91235E0EDB00C160A2 /* DigitBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A8321AE2355FE9500CB7F00 /* DigitBox.swift */; }; 0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */; }; + 0A25209624645AFD000FA9F6 /* TextViewEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A25209524645AFD000FA9F6 /* TextViewEntryField.swift */; }; + 0A25209824645B76000FA9F6 /* TextViewEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A25209724645B76000FA9F6 /* TextViewEntryFieldModel.swift */; }; 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; }; 0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */; }; 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */; }; @@ -76,7 +78,6 @@ 0A6682AA2435125F00AD3CA1 /* Styler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682A92435125F00AD3CA1 /* Styler.swift */; }; 0A6682AC243531C300AD3CA1 /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682AB243531C300AD3CA1 /* Padding.swift */; }; 0A6682B5243769C700AD3CA1 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682B3243769C700AD3CA1 /* TextView.swift */; }; - 0A6682B6243769C700AD3CA1 /* TextViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682B4243769C700AD3CA1 /* TextViewModel.swift */; }; 0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */; }; 0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; }; 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; }; @@ -91,6 +92,7 @@ 0A7EF86323D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86223D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift */; }; 0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */; }; 0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */; }; + 0A849EFE246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A849EFD246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift */; }; 0A9D091D2433796500D2E6C0 /* BarsCarouselIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D09172433796500D2E6C0 /* BarsCarouselIndicatorModel.swift */; }; 0A9D091E2433796500D2E6C0 /* NumericCarouselIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D09182433796500D2E6C0 /* NumericCarouselIndicatorModel.swift */; }; 0A9D091F2433796500D2E6C0 /* NumericIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D09192433796500D2E6C0 /* NumericIndicatorView.swift */; }; @@ -108,6 +110,8 @@ 0AE98BB523FF18D2004C5109 /* Arrow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB423FF18D2004C5109 /* Arrow.swift */; }; 0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB623FF18E9004C5109 /* ArrowModel.swift */; }; 279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */; }; + 27F973532466074500CAB5C5 /* PageBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F973522466074500CAB5C5 /* PageBehavior.swift */; }; + 27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.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 */; }; @@ -146,8 +150,6 @@ 8DE5BECF2456F7B100772E76 /* ListTwoColumnDropdownSelectors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DE5BECE2456F7B100772E76 /* ListTwoColumnDropdownSelectors.swift */; }; 8DEFA95C243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DEFA95B243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift */; }; 8DEFA95E243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DEFA95D243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift */; }; - 942C372E241149170066E45E /* NHaasGroteskDSStd-75Bd.otf in Resources */ = {isa = PBXBuildFile; fileRef = 942C372C241149170066E45E /* NHaasGroteskDSStd-75Bd.otf */; }; - 942C372F241149170066E45E /* NHaasGroteskDSStd-55Rg.otf in Resources */ = {isa = PBXBuildFile; fileRef = 942C372D241149170066E45E /* NHaasGroteskDSStd-55Rg.otf */; }; 942C378C2412F4FA0066E45E /* ModalMoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */; }; 942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 942C378D2412F5B60066E45E /* ModalMoleculeStackTemplate.swift */; }; 9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; }; @@ -179,6 +181,8 @@ 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 */; }; 94F6516D2437954100631BF9 /* Tabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94F6516C2437954100631BF9 /* Tabs.swift */; }; + AA104B1A24474A66004D2810 /* HeadersH2Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */; }; + AA104B1C24474A76004D2810 /* HeadersH2ButtonsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104B1B24474A76004D2810 /* HeadersH2ButtonsModel.swift */; }; AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA11A41E23F15D3100D7962F /* ListRightVariablePayments.swift */; }; AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */; }; AA1EC59724373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA1EC59624373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift */; }; @@ -196,6 +200,8 @@ AA85236C244435A20059CC1E /* RadioSwatchCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */; }; AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */; }; AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */; }; + AAB7EDEF246ADA1600E54929 /* ListProgressBarThinModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB7EDEE246ADA1600E54929 /* ListProgressBarThinModel.swift */; }; + AAB7EDF1246ADA2A00E54929 /* ListProgressBarThin.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB7EDF0246ADA2A00E54929 /* ListProgressBarThin.swift */; }; AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; }; AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatch.swift */; }; AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; }; @@ -478,6 +484,8 @@ 0A21DB7E235DECC500C160A2 /* EntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryField.swift; sourceTree = ""; }; 0A21DB82235DFBC500C160A2 /* MdnEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MdnEntryField.swift; sourceTree = ""; }; 0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitEntryField.swift; sourceTree = ""; }; + 0A25209524645AFD000FA9F6 /* TextViewEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewEntryField.swift; sourceTree = ""; }; + 0A25209724645B76000FA9F6 /* TextViewEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewEntryFieldModel.swift; sourceTree = ""; }; 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CATransaction+Extension.swift"; sourceTree = ""; }; 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = ""; }; 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleGuidelinesProtocol.swift; sourceTree = ""; }; @@ -486,7 +494,6 @@ 0A6682A92435125F00AD3CA1 /* Styler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Styler.swift; sourceTree = ""; }; 0A6682AB243531C300AD3CA1 /* Padding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Padding.swift; sourceTree = ""; }; 0A6682B3243769C700AD3CA1 /* TextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = ""; }; - 0A6682B4243769C700AD3CA1 /* TextViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextViewModel.swift; sourceTree = ""; }; 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyRequiredModel.swift; sourceTree = ""; }; 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseDropdownEntryField.swift; sourceTree = ""; }; 0A7918F423F5E7EA00772FF4 /* ImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageView.swift; sourceTree = ""; }; @@ -504,6 +511,7 @@ 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryFieldModel.swift; sourceTree = ""; }; 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryFieldModel.swift; sourceTree = ""; }; 0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = ""; }; + 0A849EFD246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleEqualsIgnoreCaseModel.swift; sourceTree = ""; }; 0A9D09172433796500D2E6C0 /* BarsCarouselIndicatorModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BarsCarouselIndicatorModel.swift; sourceTree = ""; }; 0A9D09182433796500D2E6C0 /* NumericCarouselIndicatorModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumericCarouselIndicatorModel.swift; sourceTree = ""; }; 0A9D09192433796500D2E6C0 /* NumericIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumericIndicatorView.swift; sourceTree = ""; }; @@ -522,6 +530,8 @@ 0AE98BB423FF18D2004C5109 /* Arrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arrow.swift; sourceTree = ""; }; 0AE98BB623FF18E9004C5109 /* ArrowModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrowModel.swift; sourceTree = ""; }; 279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionModelAdapter.swift; sourceTree = ""; }; + 27F973522466074500CAB5C5 /* PageBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehavior.swift; sourceTree = ""; }; + 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBrightnessModifierBehavior.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 = ""; }; @@ -561,8 +571,6 @@ 8DEFA95B243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnDataUsageDividerModel.swift; sourceTree = ""; }; 8DEFA95D243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnDataUsageDivider.swift; sourceTree = ""; }; 9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = ""; }; - 942C372C241149170066E45E /* NHaasGroteskDSStd-75Bd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NHaasGroteskDSStd-75Bd.otf"; sourceTree = ""; }; - 942C372D241149170066E45E /* NHaasGroteskDSStd-55Rg.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NHaasGroteskDSStd-55Rg.otf"; sourceTree = ""; }; 942C378B2412F4FA0066E45E /* ModalMoleculeListTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalMoleculeListTemplate.swift; sourceTree = ""; }; 942C378D2412F5B60066E45E /* ModalMoleculeStackTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalMoleculeStackTemplate.swift; sourceTree = ""; }; 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = ""; }; @@ -593,6 +601,8 @@ 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 = ""; }; 94F6516C2437954100631BF9 /* Tabs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tabs.swift; sourceTree = ""; }; + AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2Buttons.swift; sourceTree = ""; }; + AA104B1B24474A76004D2810 /* HeadersH2ButtonsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2ButtonsModel.swift; sourceTree = ""; }; AA11A41E23F15D3100D7962F /* ListRightVariablePayments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePayments.swift; sourceTree = ""; }; AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePaymentsModel.swift; sourceTree = ""; }; AA1EC59624373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnSpeedTestDividerModel.swift; sourceTree = ""; }; @@ -610,6 +620,8 @@ AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchCollectionViewCell.swift; sourceTree = ""; }; AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyText.swift; sourceTree = ""; }; AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyTextModel.swift; sourceTree = ""; }; + AAB7EDEE246ADA1600E54929 /* ListProgressBarThinModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListProgressBarThinModel.swift; sourceTree = ""; }; + AAB7EDF0246ADA2A00E54929 /* ListProgressBarThin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListProgressBarThin.swift; sourceTree = ""; }; AAB9C10724346F4B00151545 /* RadioSwatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatches.swift; sourceTree = ""; }; AAB9C109243496DD00151545 /* RadioSwatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatch.swift; sourceTree = ""; }; AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.swift; sourceTree = ""; }; @@ -875,6 +887,7 @@ 011D95A0240453D0000E3791 /* RuleEqualsModel.swift */, 011D95A2240453F8000E3791 /* RuleRegexModel.swift */, 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */, + 0A849EFD246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift */, ); name = Rules; path = Rules/Rules; @@ -956,6 +969,15 @@ path = Adapters; sourceTree = ""; }; + 27F973512466071600CAB5C5 /* Behaviors */ = { + isa = PBXGroup; + children = ( + 27F973522466074500CAB5C5 /* PageBehavior.swift */, + 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */, + ); + path = Behaviors; + sourceTree = ""; + }; 5206F150241144A900658DC5 /* Headers */ = { isa = PBXGroup; children = ( @@ -963,6 +985,8 @@ AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */, AA26850D244840C300CE34CC /* HeadersH2TinyButtonModel.swift */, AA26850B244840AE00CE34CC /* HeadersH2TinyButton.swift */, + AA104B1B24474A76004D2810 /* HeadersH2ButtonsModel.swift */, + AA104B1924474A66004D2810 /* HeadersH2Buttons.swift */, ); path = Headers; sourceTree = ""; @@ -1248,6 +1272,8 @@ D20492F12434CB5F00A5EED6 /* FourColumn */, AA4FC2A323F4F69600E251DB /* RightVariable */, D22B38EB23F4E0AE00490EF6 /* LeftVariable */, + AAB7EDEE246ADA1600E54929 /* ListProgressBarThinModel.swift */, + AAB7EDF0246ADA2A00E54929 /* ListProgressBarThin.swift */, ); path = List; sourceTree = ""; @@ -1400,6 +1426,7 @@ D29DF0CE21E404D4003B2FB9 /* MVMCoreUI */ = { isa = PBXGroup; children = ( + 27F973512466071600CAB5C5 /* Behaviors */, D2C78CD324252F4E00B69FDE /* Atomic */, 012A88EF23985E0100FE3DA1 /* CustomPrimitives */, D2B18B7D236090D500A9AEDC /* BaseClasses */, @@ -1655,6 +1682,8 @@ 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */, 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */, 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */, + 0A25209724645B76000FA9F6 /* TextViewEntryFieldModel.swift */, + 0A25209524645AFD000FA9F6 /* TextViewEntryField.swift */, ); path = TextFields; sourceTree = ""; @@ -1725,8 +1754,6 @@ 94CA227924058533002D6750 /* VerizonNHGeDS-Regular.otf */, 94CA227824058533002D6750 /* VerizonNHGeTX-Bold.otf */, 94CA227B24058533002D6750 /* VerizonNHGeTX-Regular.otf */, - 942C372D241149170066E45E /* NHaasGroteskDSStd-55Rg.otf */, - 942C372C241149170066E45E /* NHaasGroteskDSStd-75Bd.otf */, D29DF31721ECECC0003B2FB9 /* OCRAExtended.ttf */, ); path = Fonts; @@ -1765,7 +1792,6 @@ D2B18B7D236090D500A9AEDC /* BaseClasses */ = { isa = PBXGroup; children = ( - 0A6682B4243769C700AD3CA1 /* TextViewModel.swift */, 0A6682B3243769C700AD3CA1 /* TextView.swift */, C003506023AA94CD00B6AC29 /* Button.swift */, D2B18B7E2360913400A9AEDC /* Control.swift */, @@ -1913,8 +1939,6 @@ D29DF32C21EE8736003B2FB9 /* Localizable.strings in Resources */, 94CA227D24058534002D6750 /* VerizonNHGeDS-Regular.otf in Resources */, D29DF32E21EE8C3D003B2FB9 /* Media.xcassets in Resources */, - 942C372E241149170066E45E /* NHaasGroteskDSStd-75Bd.otf in Resources */, - 942C372F241149170066E45E /* NHaasGroteskDSStd-55Rg.otf in Resources */, 94CA227E24058534002D6750 /* VerizonNHGeDS-Bold.otf in Resources */, D287651A245B338E00CB882D /* VerizonNHGeTX-Regular.otf in Resources */, D29DF31B21ECECC0003B2FB9 /* OCRAExtended.ttf in Resources */, @@ -2044,10 +2068,12 @@ 943820842432382400B43AF3 /* WebView.swift in Sources */, 0103B84E23D7E33A009C315C /* HeadlineBodyToggleModel.swift in Sources */, D2755D7B23689C7500485468 /* TableViewCell.swift in Sources */, + 0A25209624645AFD000FA9F6 /* TextViewEntryField.swift in Sources */, 014AA72623C501E2006F3E93 /* ContainerModelProtocol.swift in Sources */, AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */, 011D9626240EBB16000E3791 /* RadioButtonLabelModel.swift in Sources */, 8DDD6C1D244D90B8006A2232 /* ListThreeColumnDataUsage.swift in Sources */, + 0A849EFE246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift in Sources */, D28764FB245A33A500CB882D /* TwoLinkViewModel.swift in Sources */, AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */, D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */, @@ -2148,6 +2174,7 @@ AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */, D264FAA3243E632F00D98315 /* ProgrammaticCollectionViewController.swift in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, + 27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, 526A265E240D200500B0D828 /* ListTwoColumnCompareChanges.swift in Sources */, 8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */, @@ -2158,7 +2185,6 @@ 012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */, 0A9D091E2433796500D2E6C0 /* NumericCarouselIndicatorModel.swift in Sources */, D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */, - 0A6682B6243769C700AD3CA1 /* TextViewModel.swift in Sources */, 9445890E2385C3F800DE9FD4 /* MultiProgressModel.swift in Sources */, 011D95A5240455DC000E3791 /* FormGroupRule.swift in Sources */, D2A6390522CBCE160052ED1F /* MoleculeCollectionViewCell.swift in Sources */, @@ -2200,6 +2226,7 @@ C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */, 01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */, D27CD4102339057800C1DC07 /* EyebrowHeadlineBodyLink.swift in Sources */, + AAB7EDF1246ADA2A00E54929 /* ListProgressBarThin.swift in Sources */, 8D070BB2241B56AD0099AC56 /* ListRightVariableTotalData.swift in Sources */, D264FAA5243F66A500D98315 /* CollectionTemplateItemProtocol.swift in Sources */, D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */, @@ -2240,6 +2267,7 @@ D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */, D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */, D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */, + 27F973532466074500CAB5C5 /* PageBehavior.swift in Sources */, 94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */, D28A838523CCCA8900DFE4FC /* ScrollerModel.swift in Sources */, D29DF26C21E6AA0B003B2FB9 /* FLAnimatedImage.m in Sources */, @@ -2251,10 +2279,12 @@ C003506123AA94CD00B6AC29 /* Button.swift in Sources */, DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */, D264FA90243BCE6800D98315 /* ThreeLayerCollectionViewController.swift in Sources */, + AA104B1C24474A76004D2810 /* HeadersH2ButtonsModel.swift in Sources */, 0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */, BB6C6AC824225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift in Sources */, 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */, D21B7F73243BAC6800051ABF /* CollectionItemModelProtocol.swift in Sources */, + AA104B1A24474A66004D2810 /* HeadersH2Buttons.swift in Sources */, C7192E7D23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift in Sources */, D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */, BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */, @@ -2277,6 +2307,7 @@ AA26850C244840AE00CE34CC /* HeadersH2TinyButton.swift in Sources */, 011D95AB2405C553000E3791 /* FormItemProtocol.swift in Sources */, D21EE53C23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift in Sources */, + 0A25209824645B76000FA9F6 /* TextViewEntryFieldModel.swift in Sources */, 525019DD2406430800EED91C /* ListProgressBarDataModel.swift in Sources */, C6FA7D5223C77A4A00A3614A /* UnOrderedList.swift in Sources */, 01509D8F2327EC6F00EF99AA /* MoleculeTableViewCell.swift in Sources */, @@ -2284,6 +2315,7 @@ EA5124FD243601600051A3A4 /* BGImageHeadlineBodyButton.swift in Sources */, 0105618D224BBE7700E1557D /* FormValidator.swift in Sources */, 01509D912327ECE600EF99AA /* CornerLabels.swift in Sources */, + AAB7EDEF246ADA1600E54929 /* ListProgressBarThinModel.swift in Sources */, D21B7F75243BAC8900051ABF /* CarouselItem.swift in Sources */, C695A69823C990C200BFB94E /* DoughnutChartView.swift in Sources */, 8D3BA9BD2433787000D341BA /* ListThreeColumnInternationalDataDividerModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift index b437a56f..d23a2606 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift @@ -71,7 +71,7 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { } public override func updateView(_ size: CGFloat) { - titleLabel?.font = MFStyler.fontB1() + titleLabel?.font = MFStyler.fontBoldBodySmall() } //------------------------------------------------------ diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioButton.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioButton.swift index 2b22fcee..1ac28ded 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioButton.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioButton.swift @@ -20,7 +20,7 @@ import UIKit } } - public override var isSelected: Bool { + @objc public override var isSelected: Bool { didSet { radioModel?.state = isSelected updateAccessibilityLabel() @@ -127,7 +127,7 @@ import UIKit func updateAccessibilityLabel() { if let state = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "radio_selected_state" : "radio_not_selected_state") { - accessibilityLabel = String(format: MVMCoreUIUtility.hardcodedString(withKey: "radio_desc_state") ?? "%@%@", "", state) + accessibilityLabel = state } } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonSelectionHelper.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonSelectionHelper.swift index 5196bb9c..4765766b 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonSelectionHelper.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonSelectionHelper.swift @@ -19,22 +19,22 @@ import Foundation private var selectedRadioButton: RadioButton? private var selectedRadioButtonModel: RadioButtonModel? public var baseValue: AnyHashable? - -//-------------------------------------------------- -// MARK: - Initializer -//-------------------------------------------------- - + + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public func set(_ radioButtonModel: RadioButtonModel, _ radioButton: RadioButton) { self.fieldKey = radioButtonModel.fieldKey self.groupName = radioButtonModel.groupName - + if radioButtonModel.state { if self.baseValue == nil, let selected = radioButtonModel.baseValue as? Bool, selected { self.baseValue = radioButtonModel.fieldValue } selectedRadioButtonModel = radioButtonModel - + // Below code is needed for cell resuse scenario. radioButton.isSelected = true selectedRadioButton = radioButton @@ -50,24 +50,24 @@ import Foundation public static func setupForRadioButtonGroup(_ radioButtonModel: RadioButtonModel, _ radioButton: RadioButton, delegateObject: MVMCoreUIDelegateObject?) { guard let groupName = radioButtonModel.fieldKey, - let formValidator = delegateObject?.formHolderDelegate?.formValidator else { - return - } - + let formValidator = delegateObject?.formHolderDelegate?.formValidator + else { return } + let radioButtonSelectionHelper = formValidator.radioButtonsModelByGroup[groupName] ?? RadioButtonSelectionHelper() radioButtonSelectionHelper.set(radioButtonModel, radioButton) formValidator.radioButtonsModelByGroup[groupName] = radioButtonSelectionHelper FormValidator.setupValidation(for: radioButtonSelectionHelper, delegate: delegateObject?.formHolderDelegate) } - + public func selected(_ radioButton: RadioButton) { + // Checks because the view could be reused if selectedRadioButton?.radioModel === selectedRadioButtonModel { selectedRadioButton?.isSelected = false } else { selectedRadioButtonModel?.state = false } - + selectedRadioButton = radioButton selectedRadioButton?.isSelected = true selectedRadioButtonModel = selectedRadioButton?.radioModel @@ -76,6 +76,7 @@ import Foundation // MARK: - FormValidationFormFieldProtocol extension RadioButtonSelectionHelper { + public func formFieldValue() -> AnyHashable? { return selectedRadioButtonModel?.fieldValue } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatch.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatch.swift index 35294457..d7413e07 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatch.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatch.swift @@ -6,9 +6,9 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation import UIKit + open class RadioSwatch: Control { //-------------------------------------------------- // MARK: - Properties diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift index 1fe0b1af..e54cb80f 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift @@ -69,6 +69,7 @@ import UIKit get { return entryFieldContainer.showError } set (error) { self.feedback = error ? entryFieldModel?.errorMessage : entryFieldModel?.feedback + self.feedbackLabel.textColor = error ? entryFieldModel?.errorTextColor?.uiColor ?? .mvmBlack : .mvmBlack self.entryFieldContainer.showError = error self.entryFieldModel?.showError = error } @@ -215,11 +216,10 @@ import UIKit entryFieldContainer.refreshUI() } - /** - Method to override. - Intended to add the interactive content (i.e. textField) to the entryFieldContainer. - */ - @objc open func setupFieldContainerContent(_ container: UIView) { } + /// Intended to add the interactive content (i.e. textField) to the entryFieldContainer. + @objc open func setupFieldContainerContent(_ container: UIView) { + // To Be Overriden + } @objc open override func updateView(_ size: CGFloat) { super.updateView(size) @@ -242,6 +242,7 @@ import UIKit titleLabel.textColor = .mvmBlack feedbackLabel.font = Styler.Font.RegularMicro.getFont() feedbackLabel.textColor = .mvmBlack + entryFieldContainer.disableAllBorders = false feedbackLabel.text = nil entryFieldContainer.reset() } @@ -257,6 +258,7 @@ import UIKit title = model.title feedback = model.feedback isEnabled = model.enabled + entryFieldContainer.disableAllBorders = model.hideBorders if let isLocked = model.locked { self.isLocked = isLocked diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift index f7886848..1d6e9221 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift @@ -22,8 +22,10 @@ import Foundation public var title: String? public var feedback: String? public var errorMessage: String? + public var errorTextColor: Color? public var enabled: Bool = true public var showError: Bool? + public var hideBorders = false public var locked: Bool? public var selected: Bool? public var text: String? @@ -37,7 +39,7 @@ import Foundation } /// Temporary binding mechanism for the view to update on enable changes. - public var updateUI: (() -> ())? + public var updateUI: ActionBlock? //-------------------------------------------------- // MARK: - Keys @@ -50,9 +52,11 @@ import Foundation case enabled case feedback case errorMessage + case errorTextColor case locked case selected case showError + case hideBorders case text case fieldKey case groupName @@ -67,7 +71,12 @@ import Foundation } public func setValidity(_ valid: Bool, rule: RulesProtocol) { + if let fieldKey = fieldKey, + let ruleErrorMessage = rule.errorMessage?[fieldKey] { + self.errorMessage = ruleErrorMessage + } self.isValid = valid + } //-------------------------------------------------- @@ -89,10 +98,12 @@ import Foundation title = try typeContainer.decodeIfPresent(String.self, forKey: .title) feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback) errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage) + errorTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .errorTextColor) enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked) selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) text = try typeContainer.decodeIfPresent(String.self, forKey: .text) + hideBorders = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideBorders) ?? false baseValue = text fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) @@ -111,8 +122,10 @@ import Foundation try container.encodeIfPresent(locked, forKey: .locked) try container.encodeIfPresent(showError, forKey: .showError) try container.encodeIfPresent(selected, forKey: .selected) + try container.encodeIfPresent(errorTextColor, forKey: .errorTextColor) try container.encodeIfPresent(errorMessage, forKey: .errorMessage) try container.encode(enabled, forKey: .enabled) + try container.encode(hideBorders, forKey: .hideBorders) try container.encodeIfPresent(fieldKey, forKey: .fieldKey) try container.encodeIfPresent(groupName, forKey: .groupName) } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 894fadd4..9d7c8927 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -244,14 +244,21 @@ import UIKit self.isValid = isValid if previousValidity && !isValid { - showError = true - observingTextFieldDelegate?.isInvalid?(textfield: self) + shouldShowError(true) } else if (!previousValidity && isValid) { - showError = false - observingTextFieldDelegate?.isValid?(textfield: self) + shouldShowError(false) + } + } + + func shouldShowError(_ showError: Bool) { + self.showError = showError + if showError { + observingTextFieldDelegate?.isValid?(textfield: self) + entryFieldContainer.originalUI() + } else { + observingTextFieldDelegate?.isInvalid?(textfield: self) } } - /// Executes on UITextField.textDidBeginEditingNotification @objc func startEditing() { isSelected = true @@ -268,10 +275,16 @@ import UIKit /// Executes on UITextField.textDidEndEditingNotification @objc func endInputing() { resignFirstResponder() - if isValid { - showError = false - entryFieldContainer.bottomBar?.backgroundColor = UIColor.mvmBlack.cgColor + + // Don't show error till user starts typing. + guard text?.count ?? 0 != 0 else { + return } + + if let isValid = (model as? TextEntryFieldModel)?.isValid { + self.isValid = isValid + } + shouldShowError(!isValid) } @objc public func dismissFieldInput(_ sender: Any?) { diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift index d47b9802..db5f3724 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift @@ -31,6 +31,7 @@ public var placeholder: String? public var enabledTextColor: Color = Color(uiColor: .mvmBlack) public var disabledTextColor: Color = Color(uiColor: .mvmCoolGray3) + public var textAlignment: NSTextAlignment = .left public var type: EntryType? //-------------------------------------------------- @@ -39,6 +40,7 @@ private enum CodingKeys: String, CodingKey { case placeholder + case textAlignment case enabledTextColor case disabledTextColor case type @@ -51,6 +53,7 @@ required public init(from decoder: Decoder) throws { try super.init(from: decoder) let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder) type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type) @@ -61,12 +64,17 @@ if let disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor) { self.disabledTextColor = disabledTextColor } + + if let textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment) { + self.textAlignment = textAlignment + } } public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(placeholder, forKey: .placeholder) + try container.encodeIfPresent(textAlignment, forKey: .textAlignment) try container.encode(enabledTextColor, forKey: .enabledTextColor) try container.encode(disabledTextColor, forKey: .disabledTextColor) try container.encodeIfPresent(type, forKey: .type) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift new file mode 100644 index 00000000..546b5c30 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift @@ -0,0 +1,279 @@ +// +// TextViewEntryField.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 5/7/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + + +class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDelegate { + //-------------------------------------------------- + // MARK: - Outlets + //-------------------------------------------------- + + open private(set) var textView: TextView = { + let textView = TextView() + textView.setContentCompressionResistancePriority(.required, for: .vertical) + return textView + }() + + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + /// Validate on each entry in the textView. Default: true + public var validateEachCharacter: Bool = true + + private var observingForChange: Bool = false + + //-------------------------------------------------- + // MARK: - Computed Properties + //-------------------------------------------------- + + public var textViewEntryFieldModel: TextViewEntryFieldModel? { + return model as? TextViewEntryFieldModel + } + + public override var isEnabled: Bool { + get { return super.isEnabled } + set (enabled) { + super.isEnabled = enabled + + DispatchQueue.main.async { [weak self] in + guard let self = self else { return } + + self.textView.isEnabled = enabled + if self.textView.isShowingPlaceholder { + self.textView.textColor = self.textView.placeholderTextColor + } else { + self.textView.textColor = (enabled ? self.textViewEntryFieldModel?.enabledTextColor : self.textViewEntryFieldModel?.disabledTextColor)?.uiColor + } + } + } + } + + public override var showError: Bool { + get { return super.showError } + set (error) { + + if error { + textView.accessibilityValue = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textView_error_message") ?? "", textView.text ?? "", entryFieldModel?.errorMessage ?? "") + } else { + textView.accessibilityValue = nil + } + + super.showError = error + } + } + + /// The text of this textView. + open override var text: String? { + get { return textView.text } + set { + textView.text = newValue + textViewEntryFieldModel?.text = newValue + } + } + + /// Placeholder access for the textView. + public var placeholder: String? { + get { return textViewEntryFieldModel?.placeholder } + set { + textView.placeholder = newValue ?? "" + textViewEntryFieldModel?.placeholder = newValue + textView.setPlaceholderIfAvailable() + } + } + + //-------------------------------------------------- + // MARK: - Constraint + //-------------------------------------------------- + + public var heightConstraint: NSLayoutConstraint? + private var topConstraint: NSLayoutConstraint? + private var leadingConstraint: NSLayoutConstraint? + private var trailingConstraint: NSLayoutConstraint? + private var bottomConstraint: NSLayoutConstraint? + + private func adjustMarginConstraints(constant: CGFloat) { + + topConstraint?.constant = constant + leadingConstraint?.constant = constant + trailingConstraint?.constant = constant + bottomConstraint?.constant = constant + } + + //-------------------------------------------------- + // MARK: - Delegate Properties + //-------------------------------------------------- + + /// The delegate and block for validation. Validates if the text that the user has entered. + public weak var observingTextViewDelegate: ObservingTextFieldDelegate? { + didSet { + if observingTextViewDelegate != nil && !observingForChange { + observingForChange = true + NotificationCenter.default.addObserver(self, selector: #selector(valueChanged), name: UITextView.textDidChangeNotification, object: textView) + NotificationCenter.default.addObserver(self, selector: #selector(endInputing), name: UITextView.textDidEndEditingNotification, object: textView) + NotificationCenter.default.addObserver(self, selector: #selector(startEditing), name: UITextView.textDidBeginEditingNotification, object: textView) + + } else if observingTextViewDelegate == nil && observingForChange { + observingForChange = false + NotificationCenter.default.removeObserver(self, name: UITextView.textDidChangeNotification, object: textView) + NotificationCenter.default.removeObserver(self, name: UITextView.textDidEndEditingNotification, object: textView) + NotificationCenter.default.removeObserver(self, name: UITextView.textDidBeginEditingNotification, object: textView) + } + } + } + + /// If you're using a ViewController, you must set this to it + public weak var uiTextViewDelegate: UITextViewDelegate? { + get { return textView.delegate } + set { textView.delegate = newValue } + } + + @objc public func setBothTextDelegates(to delegate: (UITextViewDelegate & ObservingTextFieldDelegate)?) { + observingTextViewDelegate = delegate + uiTextViewDelegate = delegate + } + + open func setupTextViewToolbar() { + let observingDelegate = observingTextViewDelegate ?? self + textView.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate, + action: #selector(observingDelegate.dismissFieldInput)) + } + + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + + @objc open override func setupFieldContainerContent(_ container: UIView) { + + container.addSubview(textView) + + topConstraint = textView.topAnchor.constraint(equalTo: container.topAnchor, constant: Padding.Three) + leadingConstraint = textView.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: Padding.Three) + trailingConstraint = container.trailingAnchor.constraint(equalTo: textView.trailingAnchor, constant: Padding.Three) + bottomConstraint = container.bottomAnchor.constraint(equalTo: textView.bottomAnchor, constant: Padding.Three) + + topConstraint?.isActive = true + leadingConstraint?.isActive = true + trailingConstraint?.isActive = true + bottomConstraint?.isActive = true + + heightConstraint = textView.heightAnchor.constraint(equalToConstant: 0) + accessibilityElements = [titleLabel, textView, feedbackLabel] + } + + open override func updateView(_ size: CGFloat) { + super.updateView(size) + textView.updateView(size) + } + + open override func reset() { + super.reset() + + textView.reset() + adjustMarginConstraints(constant: Padding.Three) + heightConstraint?.constant = 0 + heightConstraint?.isActive = false + } + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + + /// Validates the text of the entry field. + @objc public func validateTextView() { + text = textView.text + if let isValid = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) { + self.isValid = isValid + } + } + + /// Executes on UITextView.textDidBeginEditingNotification + @objc func startEditing() { + isSelected = true + _ = textView.becomeFirstResponder() + } + + /// Executes on UITextView.textDidChangeNotification (each character entry) + @objc func valueChanged() { + guard validateEachCharacter else { return } + validateTextView() + } + + /// Executes on UITextView.textDidEndEditingNotification + @objc func endInputing() { + resignFirstResponder() + isSelected = false + showError = !isValid + } + + //-------------------------------------------------- + // MARK: - MoleculeViewProtocol + //-------------------------------------------------- + + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) + + guard let model = model as? TextViewEntryFieldModel else { return } + + if let height = model.height { + heightConstraint?.constant = height + heightConstraint?.isActive = true + } + + text = model.text + uiTextViewDelegate = delegateObject?.uiTextViewDelegate + observingTextViewDelegate = delegateObject?.observingTextFieldDelegate + + if let accessibilityText = model.accessibilityText { + accessibilityLabel = accessibilityText + } + + textView.isEditable = model.editable + textView.textAlignment = model.textAlignment + textView.textColor = model.enabled ? model.enabledTextColor.uiColor : model.disabledTextColor.uiColor + textView.font = model.fontStyle.getFont() + textView.placeholder = model.placeholder ?? "" + textView.placeholderFontStyle = model.placeholderFontStyle + textView.placeholderTextColor = model.placeholderTextColor.uiColor + textView.setPlaceholderIfAvailable() + + switch model.type { + case .secure, .password: + textView.isSecureTextEntry = true + + case .number: + textView.keyboardType = .numberPad + + case .email: + textView.keyboardType = .emailAddress + + default: break + } + + /// No point in configuring if the TextView is Read-only. + if textView.isEditable { + FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) + setupTextViewToolbar() + + if isSelected { + DispatchQueue.main.async { + _ = self.textView.becomeFirstResponder() + } + } + } + + if model.hideBorders { + adjustMarginConstraints(constant: 0) + } + + if !model.enabled { + isEnabled = false + } + } +} diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryFieldModel.swift similarity index 75% rename from MVMCoreUI/BaseClasses/TextViewModel.swift rename to MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryFieldModel.swift index d9505275..ce1173ae 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryFieldModel.swift @@ -1,15 +1,15 @@ // -// TextViewModel.swift +// TextViewEntryFieldModel.swift // MVMCoreUI // -// Created by Kevin Christiano on 4/2/20. +// Created by Kevin Christiano on 5/7/20. // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation +import UIKit -open class TextViewModel: TextEntryFieldModel { +class TextViewEntryFieldModel: TextEntryFieldModel { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -19,26 +19,21 @@ open class TextViewModel: TextEntryFieldModel { } public var accessibilityText: String? - public var fontStyle: Styler.Font = Styler.Font.RegularBodySmall - public var textAlignment: NSTextAlignment = .left + public var fontStyle: Styler.Font = Styler.Font.RegularBodyLarge public var height: CGFloat? public var placeholderTextColor: Color = Color(uiColor: .mvmCoolGray3) public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro - public var showsPlaceholder: Bool = false - public var hideBorders: Bool = false public var editable: Bool = true - + public var showsPlaceholder: Bool = false + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- private enum CodingKeys: String, CodingKey { - case text case accessibilityText case fontStyle - case textAlignment case height - case hideBorders case placeholderFontStyle case placeholderTextColor case editable @@ -60,22 +55,14 @@ open class TextViewModel: TextEntryFieldModel { self.placeholderTextColor = placeholderTextColor } - if let textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment) { - self.textAlignment = textAlignment - } - - if let hideBorders = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideBorders) { - self.hideBorders = hideBorders + if let fontStyle = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .fontStyle) { + self.fontStyle = fontStyle } if let editable = try typeContainer.decodeIfPresent(Bool.self, forKey: .editable) { self.editable = editable } - if let fontStyle = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .fontStyle) { - self.fontStyle = fontStyle - } - accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) } @@ -86,11 +73,8 @@ open class TextViewModel: TextEntryFieldModel { try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) try container.encodeIfPresent(height, forKey: .height) try container.encode(fontStyle, forKey: .fontStyle) - try container.encode(hideBorders, forKey: .hideBorders) - try container.encode(text, forKey: .text) + try container.encode(editable, forKey: .editable) try container.encode(placeholderFontStyle, forKey: .placeholderFontStyle) try container.encode(placeholderTextColor, forKey: .placeholderTextColor) - try container.encode(textAlignment, forKey: .textAlignment) - try container.encode(editable, forKey: .editable) } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/NumericIndicatorView.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/NumericIndicatorView.swift index 3585be05..04ea2fcd 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/NumericIndicatorView.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/NumericIndicatorView.swift @@ -16,7 +16,7 @@ open class NumericIndicatorView: CarouselIndicator { /// Text to display the current count of total pages for viewing. open var pageCount: Label = { - let label = Label.commonLabelB2(true) + let label = Label.createLabelRegularBodySmall(true) label.isAccessibilityElement = false label.setContentCompressionResistancePriority(.required, for: .vertical) label.textAlignment = .center diff --git a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabel.swift b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabel.swift index 5d4f68be..9d203ea9 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabel.swift @@ -13,7 +13,7 @@ //-------------------------------------------------- public let checkbox = Checkbox() - public let label = Label.commonLabelB2(true) + public let label = Label.createLabelRegularBodySmall(true) //-------------------------------------------------- // MARK: - Properties diff --git a/MVMCoreUI/Atomic/Atoms/Views/Line.swift b/MVMCoreUI/Atomic/Atoms/Views/Line.swift index d34aee06..b29cb395 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Line.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Line.swift @@ -32,16 +32,16 @@ import UIKit switch style { case .standard: updateLineConstraints(constant: 1) - backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mfSilver() + backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mvmCoolGray3 case .thin: updateLineConstraints(constant: 1) - backgroundColor = lineModel?.backgroundColor?.uiColor ?? .black + backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mvmBlack case .medium: updateLineConstraints(constant: 2) - backgroundColor = lineModel?.backgroundColor?.uiColor ?? .black + backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mvmBlack case .heavy: updateLineConstraints(constant: 4) - backgroundColor = lineModel?.backgroundColor?.uiColor ?? .black + backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mvmBlack case .none: updateLineConstraints(constant: 0) } @@ -101,6 +101,7 @@ import UIKit } extension Line: MVMCoreUIViewConstrainingProtocol { + open func needsToBeConstrained() -> Bool { return true } diff --git a/MVMCoreUI/Atomic/Atoms/Views/LoadImageView.swift b/MVMCoreUI/Atomic/Atoms/Views/LoadImageView.swift index a8d0ba9a..baa63ee8 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LoadImageView.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LoadImageView.swift @@ -11,7 +11,8 @@ import UIKit @objcMembers open class LoadImageView: View { public let loadingSpinner = MFLoadingSpinner(frame: .zero) public let imageView = MFTransparentGIFView(frame: .zero) - public var addSizeConstraintsForAspectRatio = false + public var addSizeConstraintsForAspectRatio = true + public var shouldNotifyDelegateOnUpdate = true var centerX: NSLayoutConstraint? var centerY: NSLayoutConstraint? var widthConstraint: NSLayoutConstraint? @@ -172,7 +173,6 @@ import UIKit } else { heightConstraint?.isActive = false heightConstraint = imageView.heightAnchor.constraint(equalToConstant: height) - heightConstraint?.priority = UILayoutPriority(rawValue: 900) } heightConstraint?.isActive = true } @@ -182,7 +182,6 @@ import UIKit widthConstraint.constant = width } else { widthConstraint = imageView.widthAnchor.constraint(equalToConstant: width) - widthConstraint?.priority = UILayoutPriority(rawValue: 900) } widthConstraint?.isActive = true } @@ -264,16 +263,15 @@ import UIKit } let finishedLoadingBlock: MVMCoreGetImageBlock = {[weak self] (image, data, isFallbackImage) in MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in - guard let loadingImageName = self?.currentImageName, loadingImageName == imageName else { - return - } - self?.isFallbackImage = isFallbackImage - self?.loadingSpinner.pause() - let layoutWillChange = self?.layoutWillChange(width: self?.currentImageWidth, height: self?.currentImageHeight, size: image?.size) ?? false - self?.addConstraints(width: width, height: height, size: image?.size) - self?.loadingSpinnerHeightConstraint?.constant = 0 + guard let self = self, + let loadingImageName = self.currentImageName, loadingImageName == imageName else { return } + self.isFallbackImage = isFallbackImage + self.loadingSpinner.pause() + let layoutWillChange = self.shouldNotifyDelegateOnUpdate ? self.layoutWillChange(width: self.currentImageWidth, height: self.currentImageHeight, size: image?.size) : false + self.addConstraints(width: width, height: height, size: image?.size) + self.loadingSpinnerHeightConstraint?.constant = 0 if layoutWillChange { - self?.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self!) + self.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self) } completionBlock(image,data,isFallbackImage) })} diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index a9e86d50..dbff52fe 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -52,7 +52,7 @@ import Foundation try? ModelRegistry.register(LabelAttributeActionModel.self) // TextView - MoleculeObjectMapping.shared()?.register(viewClass: TextView.self, viewModelClass: TextViewModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: TextViewEntryField.self, viewModelClass: TextViewEntryFieldModel.self) // Buttons MoleculeObjectMapping.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self) @@ -162,6 +162,7 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnInternationalData.self, viewModelClass: ListThreeColumnInternationalDataModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnDataUsage.self, viewModelClass: ListThreeColumnDataUsageModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListProgressBarThin.self, viewModelClass: ListProgressBarThinModel.self) // Designed Section Dividers MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self) @@ -178,6 +179,7 @@ import Foundation // Designed Headers MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2NoButtonsBodyText.self, viewModelClass: HeadersH2NoButtonsBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2TinyButton.self, viewModelClass: HeadersH2TinyButtonModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2Buttons.self, viewModelClass: HeadersH2ButtonsModel.self) // Device Items MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonMedium.self, viewModelClass: ListDeviceComplexButtonMediumModel.self) @@ -192,12 +194,16 @@ import Foundation try? ModelRegistry.register(RuleAnyValueChangedModel.self) try? ModelRegistry.register(RuleAllValueChangedModel.self) try? ModelRegistry.register(RuleEqualsModel.self) + try? ModelRegistry.register(RuleEqualsIgnoreCaseModel.self) try? ModelRegistry.register(RuleRegexModel.self) // Actions try? ModelRegistry.register(ActionTopAlertModel.self) try? ModelRegistry.register(ActionCollapseNotificationModel.self) try? ModelRegistry.register(ActionOpenPanelModel.self) + + // Behaviors + try? ModelRegistry.register(ScreenBrightnessModifierBehavior.self) } /// Convenience function to get required modules for a give model diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2Buttons.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2Buttons.swift new file mode 100644 index 00000000..57e62d24 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2Buttons.swift @@ -0,0 +1,59 @@ +// +// HeadersH2Buttons.swift +// MVMCoreUI +// +// Created by Lekshmi S on 10/03/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class HeadersH2Buttons: HeaderView { + //-------------------------------------------------- + // MARK: - Outlets + //-------------------------------------------------- + public let headlineBody = HeadlineBody(frame: .zero) + public let buttons = TwoButtonView(frame: .zero) + public let stack: Stack + + //------------------------------------------------------- + // MARK: - Initializers + //------------------------------------------------------- + public override init(frame: CGRect) { + stack = Stack.createStack(with: [headlineBody, buttons], spacing: PaddingDefaultVerticalSpacing3) + super.init(frame: frame) + } + + public required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + //------------------------------------------------------- + // MARK: - View Lifecycle + //------------------------------------------------------- + open override func setupView() { + super.setupView() + headlineBody.stylePageHeader() + addMolecule(stack) + stack.restack() + } + + //---------------------------------------------------- + // MARK: - Molecule + //------------------------------------------------------ + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? HeadersH2ButtonsModel else { return } + headlineBody.set(with: model.headlineBody, delegateObject, additionalData) + buttons.set(with: model.buttons, delegateObject, additionalData) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 121 + } + + open override func reset() { + super.reset() + headlineBody.stylePageHeader() + } +} diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2ButtonsModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2ButtonsModel.swift new file mode 100644 index 00000000..afc57f2e --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2ButtonsModel.swift @@ -0,0 +1,60 @@ +// +// HeadersH2ButtonsModel.swift +// MVMCoreUI +// +// Created by Lekshmi S on 10/03/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class HeadersH2ButtonsModel: HeaderModel, MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "headerH2Btns" + public var headlineBody: HeadlineBodyModel + public var buttons: TwoButtonViewModel + + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(headlineBody: HeadlineBodyModel, buttons: TwoButtonViewModel) { + self.headlineBody = headlineBody + self.buttons = buttons + super.init() + } + + public override func setDefaults() { + super.setDefaults() + topPadding = PaddingDefaultVerticalSpacing3 + bottomPadding = PaddingDefaultVerticalSpacing3 + } + + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { + case moleculeName + case headlineBody + case buttons + } + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody) + buttons = try typeContainer.decode(TwoButtonViewModel.self, forKey: .buttons) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(headlineBody, forKey: .headlineBody) + try container.encode(buttons, forKey: .buttons) + } +} diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2NoButtonsBodyText.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2NoButtonsBodyText.swift index 69bdbbba..8826a239 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2NoButtonsBodyText.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2NoButtonsBodyText.swift @@ -12,6 +12,7 @@ import Foundation //-------------------------------------------------- // MARK: - Outlets //-------------------------------------------------- + let headlineBody = HeadlineBody(frame: .zero) //------------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2TinyButton.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2TinyButton.swift index 0991eec6..788a6a89 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2TinyButton.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/HeadersH2TinyButton.swift @@ -14,7 +14,19 @@ import Foundation //-------------------------------------------------- public let headlineBody = HeadlineBody(frame: .zero) public let button = PillButton(frame: .zero) - public var stack = Stack(frame: .zero) + public let stack: Stack + + //------------------------------------------------------- + // MARK: - Initializers + //------------------------------------------------------- + public override init(frame: CGRect) { + stack = Stack.createStack(with: [(view: headlineBody, model: StackItemModel(horizontalAlignment: .fill)), (view: button, model: StackItemModel(spacing: spacingBetwenHeadlineBodyAndButton, horizontalAlignment: .leading))], axis: .vertical) + super.init(frame: frame) + } + + public required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } //------------------------------------------------------ // MARK: - Constants @@ -26,7 +38,6 @@ import Foundation //------------------------------------------------------- open override func setupView() { super.setupView() - stack = Stack.createStack(with: [(view: headlineBody, model: StackItemModel(horizontalAlignment: .fill)), (view: button, model: StackItemModel(spacing: spacingBetwenHeadlineBodyAndButton, horizontalAlignment: .leading))], axis: .vertical) headlineBody.stylePageHeader() addMolecule(stack) stack.restack() diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonMedium.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonMedium.swift index c39bce65..e6e226cb 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonMedium.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonMedium.swift @@ -43,6 +43,7 @@ import Foundation // MARK: - MFViewProtocol open override func setupView() { super.setupView() + rightImageView.shouldNotifyDelegateOnUpdate = false addMolecule(stack) stack.restack() verticalStack.restack() diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonSmall.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonSmall.swift index 77a189c2..e8436620 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonSmall.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexButtonSmall.swift @@ -43,6 +43,7 @@ import Foundation // MARK: - MFViewProtocol open override func setupView() { super.setupView() + rightImageView.shouldNotifyDelegateOnUpdate = false addMolecule(stack) stack.restack() verticalStack.restack() diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexLinkMedium.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexLinkMedium.swift index f53da09c..573335c0 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexLinkMedium.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexLinkMedium.swift @@ -46,6 +46,7 @@ import Foundation //----------------------------------------------------- open override func setupView() { super.setupView() + rightImage.shouldNotifyDelegateOnUpdate = false addMolecule(stack) stack.restack() verticalStack.restack() diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexLinkSmall.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexLinkSmall.swift index 5ba8ac97..49173067 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexLinkSmall.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Device/ListDeviceComplexLinkSmall.swift @@ -46,6 +46,7 @@ import Foundation //----------------------------------------------------- open override func setupView() { super.setupView() + rightImage.shouldNotifyDelegateOnUpdate = false addMolecule(stack) stack.restack() verticalStack.restack() diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/FourColumn/ListFourColumnDataUsageListItem.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/FourColumn/ListFourColumnDataUsageListItem.swift index 2377a1f2..a42b6797 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/FourColumn/ListFourColumnDataUsageListItem.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/FourColumn/ListFourColumnDataUsageListItem.swift @@ -14,10 +14,10 @@ import Foundation // MARK: - Outlets //----------------------------------------------------- var stack: Stack - let label1 = Label.commonLabelB2(true) - let label2 = Label.commonLabelB2(true) - let label3 = Label.commonLabelB2(true) - let label4 = Label.commonLabelB2(true) + let label1 = Label.createLabelRegularBodySmall(true) + let label2 = Label.createLabelRegularBodySmall(true) + let label3 = Label.createLabelRegularBodySmall(true) + let label4 = Label.createLabelRegularBodySmall(true) let arrow = Arrow(frame: .zero) let arrowAndLabel2Stack: Stack @@ -69,9 +69,9 @@ import Foundation open override func reset() { super.reset() - label1.styleB2(true) - label2.styleB2(true) - label3.styleB2(true) - label4.styleB2(true) + label1.styleRegularBodySmall(true) + label2.styleRegularBodySmall(true) + label3.styleRegularBodySmall(true) + label4.styleRegularBodySmall(true) } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift index 7031e239..db7decbd 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift @@ -6,7 +6,6 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation import UIKit @objcMembers open class ListLeftVariableIconWithRightCaret: TableViewCell { @@ -15,8 +14,8 @@ import UIKit // MARK: - Outlets //------------------------------------------------------- let leftImage = LoadImageView(pinnedEdges: .all) - let leftLabel = Label.commonLabelB2(true) - let rightLabel = Label.commonLabelB2(true) + let leftLabel = Label.createLabelRegularBodySmall(true) + let rightLabel = Label.createLabelRegularBodySmall(true) var stack: Stack //----------------------------------------------------- @@ -64,7 +63,7 @@ import UIKit open override func reset() { super.reset() - leftLabel.styleB2(true) - rightLabel.styleB2(true) + leftLabel.styleRegularBodySmall(true) + rightLabel.styleRegularBodySmall(true) } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift index ee4900c5..688f457c 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift @@ -14,11 +14,13 @@ import UIKit // MARK: - Outlets //----------------------------------------------------- - let radioButton = RadioButton(frame: .zero) + let radioButton = RadioButton() let leftImage = LoadImageView(pinnedEdges: .all) let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink() var stack: Stack + private var observation: NSKeyValueObservation? = nil + //----------------------------------------------------- // MARK: - Initializers //----------------------------------------------------- @@ -46,6 +48,16 @@ import UIKit stack.restack() eyebrowHeadlineBodyLink.body.textColor = .mvmOrangeAA eyebrowHeadlineBodyLink.headline.styleBoldBodySmall(true) + radioButton.isAccessibilityElement = false + isAccessibilityElement = true + updateAccessibilityLabel() + accessibilityTraits = .button + accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "radio_action_hint") + updateAccessibilityLabel() + + observation = observe(\.radioButton.isSelected, options: [.new]) { [weak self] _, _ in + self?.updateAccessibilityLabel() + } } open override func reset() { @@ -64,6 +76,7 @@ import UIKit radioButton.set(with: model.radioButton, delegateObject, additionalData) leftImage.set(with: model.image, delegateObject, additionalData) eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + updateAccessibilityLabel() } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { @@ -71,6 +84,34 @@ import UIKit } public override func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - radioButton.tapAction() + radioButton.tapAction() + } + + func updateAccessibilityLabel() { + + var message = MVMCoreUIUtility.hardcodedString(withKey: "radio_button") ?? "" + + radioButton.updateAccessibilityLabel() + if let radioButtonLabel = radioButton.accessibilityLabel { + message += radioButtonLabel + ", " + } + + if let leftImageLabel = leftImage.accessibilityLabel { + message += leftImageLabel + ", " + } + + if let eyebrowLabel = eyebrowHeadlineBodyLink.eyebrow.text { + message += eyebrowLabel + ", " + } + + if let headlineLabel = eyebrowHeadlineBodyLink.headline.text { + message += headlineLabel + ", " + } + + if let bodyLabel = eyebrowHeadlineBodyLink.body.text { + message += bodyLabel + } + + accessibilityLabel = message } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethodModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethodModel.swift index 5ea28778..f455882e 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethodModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethodModel.swift @@ -9,11 +9,19 @@ import Foundation public class ListLeftVariableRadioButtonAndPaymentMethodModel: ListItemModel, MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "listLVRBImg" public var radioButton: RadioButtonModel public var image: ImageViewModel public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(radioButton: RadioButtonModel, image: ImageViewModel, eyebrowHeadlineBodyLink:EyebrowHeadlineBodyLinkModel) { self.radioButton = radioButton self.image = image @@ -21,6 +29,10 @@ public class ListLeftVariableRadioButtonAndPaymentMethodModel: ListItemModel, Mo super.init() } + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + public override func setDefaults() { super.setDefaults() if image.width == nil, image.height == nil { @@ -29,6 +41,10 @@ public class ListLeftVariableRadioButtonAndPaymentMethodModel: ListItemModel, Mo } } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case radioButton @@ -36,6 +52,10 @@ public class ListLeftVariableRadioButtonAndPaymentMethodModel: ListItemModel, Mo case eyebrowHeadlineBodyLink } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) radioButton = try typeContainer.decode(RadioButtonModel.self, forKey: .radioButton) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonBodyText.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonBodyText.swift index 9b45eec7..d89604f9 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonBodyText.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonBodyText.swift @@ -14,10 +14,12 @@ open class ListLeftVariableRadioButtonBodyText: TableViewCell { // MARK: - Outlets //----------------------------------------------------- - let radioButton = RadioButton(frame: .zero) + let radioButton = RadioButton() let headlineBody = HeadlineBody() var stack: Stack + private var observation: NSKeyValueObservation? = nil + //----------------------------------------------------- // MARK: - Initializers //----------------------------------------------------- @@ -42,6 +44,15 @@ open class ListLeftVariableRadioButtonBodyText: TableViewCell { addMolecule(stack) stack.restack() + isAccessibilityElement = true + radioButton.isAccessibilityElement = false + accessibilityTraits = .button + accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "radio_action_hint") + updateAccessibilityLabel() + + observation = observe(\.radioButton.isSelected, options: [.new]) { [weak self] _, _ in + self?.updateAccessibilityLabel() + } } //---------------------------------------------------- @@ -55,6 +66,7 @@ open class ListLeftVariableRadioButtonBodyText: TableViewCell { radioButton.set(with: model.radioButton, delegateObject, additionalData) headlineBody.set(with: model.headlineBody, delegateObject, additionalData) + updateAccessibilityLabel() } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { @@ -64,4 +76,24 @@ open class ListLeftVariableRadioButtonBodyText: TableViewCell { public override func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { radioButton.tapAction() } + + func updateAccessibilityLabel() { + + var message = MVMCoreUIUtility.hardcodedString(withKey: "radio_button") ?? "" + + radioButton.updateAccessibilityLabel() + if let radioButtonLabel = radioButton.accessibilityLabel { + message += radioButtonLabel + ", " + } + + if let headlineLabel = headlineBody.headlineLabel.text { + message += headlineLabel + ", " + } + + if let messageLabel = headlineBody.messageLabel.text { + message += messageLabel + } + + accessibilityLabel = message + } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListProgressBarThin.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListProgressBarThin.swift new file mode 100644 index 00000000..072be6bb --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListProgressBarThin.swift @@ -0,0 +1,99 @@ +// +// ListProgressBarThin.swift +// MVMCoreUI +// +// Created by Lekshmi S on 12/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +@objcMembers open class ListProgressBarThin: TableViewCell { + //-------------------------------------------------- + // MARK: - Outlets + //-------------------------------------------------- + public let progressBar = ProgressBar() + public let leftHeadline = Label.commonLabelB1(true) + public let leftBody = Label.commonLabelB2(true) + public let rightBar = Line() + public let rightLabel = Label.commonLabelB2(true) + private let barStackItem: StackItem + private let rightLabelStackItem: StackItem + public var labelStack: Stack + public var horizontalStack: Stack + public var stack: Stack + + //------------------------------------------------------ + // MARK: - Initializers + //------------------------------------------------------ + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + //vertical stack with leftHeadline, leftBody + labelStack = Stack.createStack(with: [leftHeadline, leftBody], axis: .vertical, spacing: 2) + + //horizontal stack with leftHeadline, leftBody, bar, rightLabel + barStackItem = StackItem(andContain: rightBar) + rightLabelStackItem = StackItem(andContain: rightLabel) + let horizontalStackItems = [StackItem(andContain: labelStack), barStackItem, rightLabelStackItem] + let horizontalStackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .leading), StackItemModel(horizontalAlignment: .fill), StackItemModel(spacing: 5, horizontalAlignment: .fill)], + axis: .horizontal) + horizontalStack = Stack(with: horizontalStackModel, stackItems: horizontalStackItems) + + //stack with all components + stack = Stack.createStack(with: [horizontalStack, progressBar], axis: .vertical, spacing: PaddingDefaultVerticalSpacing3) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + open override func alignAccessoryToHero() -> CGPoint? { + // Ensures that the right items are centered with the arrow. + let heroCenter = super.alignAccessoryToHero() + if let heroCenter = heroCenter { + let convertedPoint = horizontalStack.convert(heroCenter, from: self) + barStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - horizontalStack.bounds.midY + rightLabelStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - horizontalStack.bounds.midY + } + return heroCenter + } + + //------------------------------------------------------- + // MARK: - View Lifecycle + //------------------------------------------------------- + open override func setupView() { + super.setupView() + rightBar.widthAnchor.constraint(equalToConstant: 20).isActive = true + rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal) + rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal) + rightLabel.numberOfLines = 1 + addMolecule(stack) + stack.restack() + horizontalStack.restack() + labelStack.restack() + } + + //------------------------------------------------------ + // MARK: - Molecule + //------------------------------------------------------ + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListProgressBarThinModel else { return } + labelStack.updateContainedMolecules(with: [model.leftHeadline, + model.leftBody], delegateObject, additionalData) + progressBar.set(with: model.progressBar, delegateObject, additionalData) + rightBar.set(with: model.rightBar, delegateObject, additionalData) + rightLabel.set(with: model.rightLabel, delegateObject, additionalData) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 120 + } + + open override func reset() { + super.reset() + leftHeadline.styleB1(true) + leftBody.styleB2(true) + rightLabel.styleB2(true) + rightBar.setStyle(.medium) + } +} diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListProgressBarThinModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListProgressBarThinModel.swift new file mode 100644 index 00000000..acd8e013 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListProgressBarThinModel.swift @@ -0,0 +1,65 @@ +// +// ListProgressBarThinModel.swift +// MVMCoreUI +// +// Created by Lekshmi S on 12/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +public class ListProgressBarThinModel: ListItemModel, MoleculeModelProtocol { + public static var identifier = "listPrgBarThin" + public var progressBar: ProgressBarModel + public var leftHeadline: LabelModel + public var leftBody: LabelModel? + public var rightBar: LineModel + public var rightLabel: LabelModel + + public init(progressBar: ProgressBarModel, leftHeadline: LabelModel, leftBody: LabelModel? = nil, rightBar: LineModel, rightLabel: LabelModel) { + self.progressBar = progressBar + self.leftHeadline = leftHeadline + self.leftBody = leftBody + self.rightBar = rightBar + self.rightLabel = rightLabel + super.init() + } + + override public func setDefaults() { + super.setDefaults() + rightBar.type = .medium + if rightBar.backgroundColor == nil { + rightBar.backgroundColor = Color(uiColor: .gray) + } + leftHeadline.hero = 0 + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case progressBar + case leftHeadline + case leftBody + case rightBar + case rightLabel + } + + public required init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + progressBar = try typeContainer.decode(ProgressBarModel.self, forKey:.progressBar) + leftHeadline = try typeContainer.decode(LabelModel.self, forKey: .leftHeadline) + leftBody = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .leftBody) + rightBar = try typeContainer.decode(LineModel.self, forKey: .rightBar) + rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(progressBar, forKey: .progressBar) + try container.encode(leftHeadline, forKey: .leftHeadline) + try container.encodeIfPresent(leftBody, forKey: .leftBody) + try container.encode(rightBar, forKey: .rightBar) + try container.encode(rightLabel, forKey: .rightLabel) + } +} diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift index 599d0cdf..2291c080 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextAllTextAndLinks.swift @@ -15,10 +15,10 @@ import Foundation //----------------------------------------------------- var stack: Stack - let eyebrow = Label.commonLabelB3(true) - let headline = Label.commonLabelH3(true) - let subHeadline = Label.commonLabelB1(true) - let body = Label.commonLabelB2(true) + let eyebrow = Label.createLabelRegularMicro(true) + let headline = Label.createLabelBoldTitleMedium(true) + let subHeadline = Label.createLabelBoldBodySmall(true) + let body = Label.createLabelRegularBodySmall(true) let link = Link() //----------------------------------------------------- @@ -62,9 +62,9 @@ import Foundation open override func reset() { super.reset() - eyebrow.styleB3(true) - headline.styleH3(true) - subHeadline.styleB1(true) - body.styleB2(true) + eyebrow.styleRegularMicro(true) + headline.styleBoldTitleMedium(true) + subHeadline.styleBoldBodySmall(true) + body.styleRegularBodySmall(true) } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRVWheel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRVWheel.swift index f7c65dbe..40579a09 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRVWheel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRVWheel.swift @@ -9,8 +9,8 @@ import Foundation @objcMembers open class ListRVWheel: TableViewCell { let wheel = Wheel(frame: .zero) - let leftLabel = Label.commonLabelB1(true) - let rightLabel = Label.commonLabelB2(true) + let leftLabel = Label.createLabelBoldBodySmall(true) + let rightLabel = Label.createLabelRegularBodySmall(true) var stack: Stack //----------------------------------------------------- @@ -54,8 +54,8 @@ import Foundation //------------------------------------------------- open override func reset() { super.reset() - leftLabel.styleB1(true) - rightLabel.styleB2(true) + leftLabel.styleBoldBodySmall(true) + rightLabel.styleRegularBodySmall(true) } public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePayments.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePayments.swift index 505f9c48..ce73c082 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePayments.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePayments.swift @@ -13,7 +13,7 @@ import Foundation //----------------------------------------------------- // MARK: - Outlets //------------------------------------------------------- - let leftLabel = Label.commonLabelB1(true) + let leftLabel = Label.createLabelBoldBodySmall(true) let rightImage = LoadImageView(pinnedEdges: .all) var stack: Stack @@ -57,6 +57,6 @@ import Foundation open override func reset() { super.reset() - leftLabel.styleB1(true) + leftLabel.styleBoldBodySmall(true) } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift index 7a74de6e..ab135eb6 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift @@ -15,7 +15,7 @@ import Foundation //----------------------------------------------------- public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) public let arrow = Arrow(frame: .zero) - public let rightLabel = Label.commonLabelB2(true) + public let rightLabel = Label.createLabelRegularBodySmall(true) private let stack: Stack private let arrowStackItem: StackItem private let rightLabelStackItem: StackItem diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift index 2b87294a..63e90d34 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift @@ -15,7 +15,7 @@ import Foundation private let stack: Stack public let headlineBody = HeadlineBody(frame: .zero) public let arrow = Arrow(frame: .zero) - public let rightLabel = Label.commonLabelB2(true) + public let rightLabel = Label.createLabelRegularBodySmall(true) let arrowAndRightLabelStack: Stack diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableTotalData.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableTotalData.swift index abef078a..bb6ebd9e 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableTotalData.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableTotalData.swift @@ -14,8 +14,8 @@ import Foundation // MARK: - Outlets //----------------------------------------------------- public var stack: Stack - public let leftLabel = Label.commonLabelB1(true) - public let rightLabel = Label.commonLabelB2(true) + public let leftLabel = Label.createLabelBoldBodySmall(true) + public let rightLabel = Label.createLabelRegularBodySmall(true) public let bar = Line() //----------------------------------------------------- @@ -61,8 +61,8 @@ import Foundation open override func reset() { super.reset() - leftLabel.styleB1(true) - rightLabel.styleB2(true) + leftLabel.styleBoldBodySmall(true) + rightLabel.styleRegularBodySmall(true) bar.setStyle(.heavy) } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/TwoColumn/ListTwoColumnCompareChanges.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/TwoColumn/ListTwoColumnCompareChanges.swift index c007b8c7..e9a78f1b 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/TwoColumn/ListTwoColumnCompareChanges.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/TwoColumn/ListTwoColumnCompareChanges.swift @@ -13,15 +13,15 @@ import Foundation //------------------------------------------------------- // MARK: - Outlets //------------------------------------------------------- - let leftHeadline1 = Label.commonLabelB1(true) - let leftHeadline2 = Label.commonLabelB1(true) - let leftHeadline3 = Label.commonLabelB1(true) - let leftBody = Label.commonLabelB2(true) + let leftHeadline1 = Label.createLabelBoldBodySmall(true) + let leftHeadline2 = Label.createLabelBoldBodySmall(true) + let leftHeadline3 = Label.createLabelBoldBodySmall(true) + let leftBody = Label.createLabelRegularBodySmall(true) let leftLink = Link() - let rightHeadline1 = Label.commonLabelB1(true) - let rightHeadline2 = Label.commonLabelB1(true) - let rightHeadline3 = Label.commonLabelB1(true) - let rightBody = Label.commonLabelB2(true) + let rightHeadline1 = Label.createLabelBoldBodySmall(true) + let rightHeadline2 = Label.createLabelBoldBodySmall(true) + let rightHeadline3 = Label.createLabelBoldBodySmall(true) + let rightBody = Label.createLabelRegularBodySmall(true) let rightLink = Link() let containingStack: Stack @@ -97,14 +97,14 @@ import Foundation open override func reset() { super.reset() - leftHeadline1.styleB1(true) - leftHeadline2.styleB1(true) - leftHeadline3.styleB1(true) - leftBody.styleB2(true) - rightHeadline1.styleB1(true) - rightHeadline2.styleB1(true) - rightHeadline3.styleB1(true) - rightBody.styleB2(true) + leftHeadline1.styleBoldBodySmall(true) + leftHeadline2.styleBoldBodySmall(true) + leftHeadline3.styleBoldBodySmall(true) + leftBody.styleRegularBodySmall(true) + rightHeadline1.styleBoldBodySmall(true) + rightHeadline2.styleBoldBodySmall(true) + rightHeadline3.styleBoldBodySmall(true) + rightBody.styleRegularBodySmall(true) } public override class func estimatedHeight(with molecule: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/TwoColumn/ListTwoColumnPriceDescription.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/TwoColumn/ListTwoColumnPriceDescription.swift index 9f4f60b2..ecae14e8 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/TwoColumn/ListTwoColumnPriceDescription.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/TwoColumn/ListTwoColumnPriceDescription.swift @@ -13,10 +13,10 @@ import Foundation //----------------------------------------------------- // MARK: - Outlets //------------------------------------------------------- - public let leftHeadline = Label.commonLabelB1(true) - public let leftBody = Label.commonLabelB2(true) - public let rightLabel = Label.commonLabelB2(true) - public let rightSubLabel = Label.commonLabelB2(true) + public let leftHeadline = Label.createLabelBoldBodySmall(true) + public let leftBody = Label.createLabelRegularBodySmall(true) + public let rightLabel = Label.createLabelRegularBodySmall(true) + public let rightSubLabel = Label.createLabelRegularBodySmall(true) public let view = MVMCoreUICommonViewsUtility.commonView() public let leftVerticalStack: UIStackView @@ -86,9 +86,9 @@ import Foundation super.reset() leftVerticalStack.reset() rightVerticalStack.reset() - leftHeadline.styleB1(true) - leftBody.styleB2(true) - rightLabel.styleB2(true) - rightSubLabel.styleB2(true) + leftHeadline.styleBoldBodySmall(true) + leftBody.styleRegularBodySmall(true) + rightLabel.styleRegularBodySmall(true) + rightSubLabel.styleRegularBodySmall(true) } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/TwoColumn/ListTwoColumnPriceDetails.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/TwoColumn/ListTwoColumnPriceDetails.swift index 43836cf0..3fbac0f3 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/TwoColumn/ListTwoColumnPriceDetails.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/TwoColumn/ListTwoColumnPriceDetails.swift @@ -10,8 +10,8 @@ import UIKit @objcMembers open class ListTwoColumnPriceDetails: TableViewCell { - let leftLabel = Label.commonLabelB2(true) - let rightLabel = Label.commonLabelB2(true) + let leftLabel = Label.createLabelRegularBodySmall(true) + let rightLabel = Label.createLabelRegularBodySmall(true) let view = MVMCoreUICommonViewsUtility.commonView() // MARK: - MFViewProtocol @@ -44,8 +44,8 @@ import UIKit super.reset() leftLabel.reset() rightLabel.reset() - leftLabel.styleB2(true) - rightLabel.styleB2(true) + leftLabel.styleRegularBodySmall(true) + rightLabel.styleRegularBodySmall(true) } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnFullWidthTextDividerSubsection.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnFullWidthTextDividerSubsection.swift index c1583583..18529ebe 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnFullWidthTextDividerSubsection.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnFullWidthTextDividerSubsection.swift @@ -13,8 +13,8 @@ import Foundation // MARK: - Outlets //----------------------------------------------------- public var stack: Stack - public let headline = Label.commonLabelB1(true) - public let body = Label.commonLabelB2(true) + public let headline = Label.createLabelBoldBodySmall(true) + public let body = Label.createLabelRegularBodySmall(true) // MARK: - Initializers public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { @@ -50,7 +50,7 @@ import Foundation open override func reset() { super.reset() - headline.styleB1(true) - body.styleB2(true) + headline.styleBoldBodySmall(true) + body.styleRegularBodySmall(true) } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerShort.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerShort.swift index ec65967d..3198a72d 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerShort.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerShort.swift @@ -13,8 +13,8 @@ import Foundation // MARK: - Outlets //----------------------------------------------------- public var stack: Stack - public let headline = Label.commonLabelH3(true) - public let body = Label.commonLabelB2(true) + public let headline = Label.createLabelBoldTitleMedium(true) + public let body = Label.createLabelRegularBodySmall(true) // MARK: - Initializers public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { @@ -50,7 +50,7 @@ import Foundation open override func reset() { super.reset() - headline.styleH3(true) - body.styleB2(true) + headline.styleBoldTitleMedium(true) + body.styleRegularBodySmall(true) } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerTall.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerTall.swift index 1f2bcd6f..d725ff61 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerTall.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerTall.swift @@ -13,8 +13,8 @@ import Foundation // MARK: - Outlets //----------------------------------------------------- public var stack: Stack - public let headline = Label.commonLabelH3(true) - public let body = Label.commonLabelB2(true) + public let headline = Label.createLabelBoldTitleMedium(true) + public let body = Label.createLabelRegularBodySmall(true) // MARK: - Initializers public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { @@ -50,7 +50,7 @@ import Foundation open override func reset() { super.reset() - headline.styleH3(true) - body.styleB2(true) + headline.styleBoldTitleMedium(true) + body.styleRegularBodySmall(true) } } diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBody.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBody.swift index 35f3ac29..ff770da3 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBody.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBody.swift @@ -18,7 +18,7 @@ import UIKit open override func setupView() { super.setupView() - headlineBody.headlineLabel.styleB1(true) + headlineBody.headlineLabel.styleBoldBodySmall(true) headlineBody.spaceBetweenLabelsConstant = 0 imageView.addSizeConstraintsForAspectRatio = true @@ -43,7 +43,7 @@ import UIKit open override func reset() { super.reset() headlineBody.reset() - headlineBody.headlineLabel.styleB1(true) + headlineBody.headlineLabel.styleBoldBodySmall(true) headlineBody.spaceBetweenLabelsConstant = 0 imageView.reset() } diff --git a/MVMCoreUI/Atomic/Molecules/Items/MoleculeListItemModel.swift b/MVMCoreUI/Atomic/Molecules/Items/MoleculeListItemModel.swift index 1384ee88..bee9d612 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/MoleculeListItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/MoleculeListItemModel.swift @@ -9,21 +9,39 @@ import Foundation import MVMCore + @objcMembers public class MoleculeListItemModel: ListItemModel, MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public class var identifier: String { return "listItem" } + public var molecule: MoleculeModelProtocol + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case molecule } + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(with moleculeModel: MoleculeModelProtocol) { molecule = moleculeModel super.init() } + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) @@ -38,4 +56,3 @@ import MVMCore try container.encodeModel(molecule, forKey: .molecule) } } - diff --git a/MVMCoreUI/Atomic/Molecules/Items/MoleculeTableViewCell.swift b/MVMCoreUI/Atomic/Molecules/Items/MoleculeTableViewCell.swift index 0c9dec3b..6e1f2965 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/MoleculeTableViewCell.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/MoleculeTableViewCell.swift @@ -10,8 +10,9 @@ import UIKit @objcMembers open class MoleculeTableViewCell: TableViewCell { - + //-------------------------------------------------- // MARK: - MoleculeViewProtocol + //-------------------------------------------------- public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImage.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImage.swift index 5dd6c722..ab0924b2 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImage.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImage.swift @@ -92,8 +92,8 @@ import UIKit private func setDefaultState() { - headlineBodyButton.headlineBody.headlineLabel.font = MFStyler.fontH3() - headlineBodyButton.headlineBody.messageLabel.font = MFStyler.fontB3() + headlineBodyButton.headlineBody.headlineLabel.font = MFStyler.fontBoldTitleMedium() + headlineBodyButton.headlineBody.messageLabel.font = MFStyler.fontRegularMicro() imageLoader.imageView.contentMode = .scaleAspectFit imageLoader.addSizeConstraintsForAspectRatio = true buttonHeaderPadding = PaddingTwo diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabels.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabels.swift index 7eb3282b..5751fbc2 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabels.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabels.swift @@ -10,10 +10,10 @@ import UIKit @objcMembers public class CornerLabels: View { var middleView: UIView? - let topLeftLabel = Label.commonLabelB1(true) - let topRightLabel = Label.commonLabelB1(true) - let bottomLeftLabel = Label.commonLabelB3(true) - let bottomRightLabel = Label.commonLabelB3(true) + let topLeftLabel = Label.createLabelBoldBodySmall(true) + let topRightLabel = Label.createLabelBoldBodySmall(true) + let bottomLeftLabel = Label.createLabelRegularMicro(true) + let bottomRightLabel = Label.createLabelRegularMicro(true) let topLabelsView = MVMCoreUICommonViewsUtility.commonView() let bottomLabelsView = MVMCoreUICommonViewsUtility.commonView() @@ -151,10 +151,10 @@ import UIKit } func styleDefault() { - topLeftLabel.styleB1(true) - topRightLabel.styleB1(true) - bottomLeftLabel.styleB3(true) - bottomRightLabel.styleB3(true) + topLeftLabel.styleBoldBodySmall(true) + topRightLabel.styleBoldBodySmall(true) + bottomLeftLabel.styleRegularMicro(true) + bottomRightLabel.styleRegularMicro(true) } public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/BGImageHeadlineBodyButtonModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/BGImageHeadlineBodyButtonModel.swift index f6fd4fcf..040b368c 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/BGImageHeadlineBodyButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/BGImageHeadlineBodyButtonModel.swift @@ -6,7 +6,6 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation import UIKit public class BGImageHeadlineBodyButtonModel: ContainerModel, MoleculeModelProtocol { diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift index dd04140b..9ad26015 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift @@ -14,9 +14,9 @@ import UIKit //-------------------------------------------------- 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 eyebrow = Label.createLabelRegularMicro(true) + public let headline = Label.createLabelBoldBodySmall(true) + public let body = Label.createLabelRegularBodySmall(true) public let link = Link() var castModel: EyebrowHeadlineBodyLinkModel? { @@ -48,9 +48,9 @@ import UIKit open override func reset() { super.reset() stack.reset() - eyebrow.styleB3(true) - headline.styleB1(true) - body.styleB2(true) + eyebrow.styleRegularMicro(true) + headline.styleBoldBodySmall(true) + body.styleRegularBodySmall(true) } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBody.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBody.swift index b36525f9..4e9b97dd 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBody.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBody.swift @@ -10,8 +10,8 @@ import UIKit open class HeadlineBody: View { - let headlineLabel = Label.commonLabelH2(true) - let messageLabel = Label.commonLabelB2(true) + let headlineLabel = Label.createLabelBoldTitleLarge(true) + let messageLabel = Label.createLabelRegularBodySmall(true) var spaceBetweenLabelsConstant = PaddingOne var spaceBetweenLabels: NSLayoutConstraint? var leftConstraintTitle: NSLayoutConstraint? @@ -39,26 +39,26 @@ open class HeadlineBody: View { } func styleLandingPageHeader() { - headlineLabel.styleH1(true) - messageLabel.styleB2(true) + headlineLabel.styleTitle2XLarge(true) + messageLabel.styleRegularBodySmall(true) spaceBetweenLabelsConstant = PaddingTwo } func stylePageHeader() { - headlineLabel.styleH2(true) - messageLabel.styleB2(true) + headlineLabel.styleBoldTitleLarge(true) + messageLabel.styleRegularBodySmall(true) spaceBetweenLabelsConstant = PaddingOne } func styleListItem() { - headlineLabel.styleB1(true) - messageLabel.styleB2(true) + headlineLabel.styleBoldBodySmall(true) + messageLabel.styleRegularBodySmall(true) spaceBetweenLabelsConstant = 0 } func styleListItemDivider() { - headlineLabel.styleH3(true) - messageLabel.styleB2(true) + headlineLabel.styleBoldTitleMedium(true) + messageLabel.styleRegularBodySmall(true) spaceBetweenLabelsConstant = 0 } diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButton.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButton.swift index 35522146..c1c3a709 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButton.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButton.swift @@ -82,8 +82,8 @@ import UIKit private func defaultState() { - headlineBody.headlineLabel.font = MFStyler.fontH3() - headlineBody.messageLabel.font = MFStyler.fontB3() + headlineBody.headlineLabel.font = MFStyler.fontBoldTitleMedium() + headlineBody.messageLabel.font = MFStyler.fontRegularMicro() button.styleSecondary() button.isHidden = false buttonHeadlinePadding = PaddingTwo diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeStack.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeStack.swift index c887e838..8630e607 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeStack.swift +++ b/MVMCoreUI/Atomic/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 open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + override open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let model = model as? StackModelProtocol, let molcules = model.molecules as? [MoleculeStackItemModel] else { return } for stackItemModel in molcules { diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeView.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeView.swift index a7c9e20d..30a82134 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeView.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeView.swift @@ -9,7 +9,7 @@ import Foundation open class StringAndMoleculeView: View { - var label = Label.commonLabelB2(true) + var label = Label.createLabelRegularBodySmall(true) var molecule: MoleculeViewProtocol var leftWidthConstraint: NSLayoutConstraint? diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift deleted file mode 100644 index 8f599be4..00000000 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// PanelNavigationItemModelProtocol.swift -// MVMCoreUI -// -// Created by Scott Pfeil on 5/18/20. -// Copyright © 2020 Verizon Wireless. All rights reserved. -// - -import Foundation - -public protocol PanelNavigationItemModelProtocol { - var showLeftPanelButton: Bool { get set } - var showRightPanelButton: Bool { get set } -} diff --git a/MVMCoreUI/Atomic/Protocols/MoleculeViewProtocol.swift b/MVMCoreUI/Atomic/Protocols/MoleculeViewProtocol.swift index 91f461dd..a8600c79 100644 --- a/MVMCoreUI/Atomic/Protocols/MoleculeViewProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/MoleculeViewProtocol.swift @@ -6,8 +6,6 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // -import Foundation - import UIKit import MVMCore.MVMCoreViewProtocol diff --git a/MVMCoreUI/Atomic/Protocols/TemplateProtocol.swift b/MVMCoreUI/Atomic/Protocols/TemplateProtocol.swift index 56b1a86c..04280042 100644 --- a/MVMCoreUI/Atomic/Protocols/TemplateProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/TemplateProtocol.swift @@ -8,7 +8,6 @@ import Foundation - public protocol TemplateProtocol: AnyObject { associatedtype TemplateModel: TemplateModelProtocol var templateModel: TemplateModel? { get set } @@ -19,6 +18,7 @@ public extension TemplateProtocol where Self: ViewController { guard let pageJSON = json else { return } let data = try JSONSerialization.data(withJSONObject: pageJSON) let decoder = JSONDecoder() + try decoder.add(delegateObject: delegateObjectIVar) let templateModel = try decoder.decode(TemplateModel.self, from: data) self.templateModel = templateModel self.pageModel = templateModel as? MVMControllerModelProtocol diff --git a/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift index e82e57a0..a141ef0e 100644 --- a/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift @@ -9,6 +9,9 @@ import UIKit open class ModalMoleculeListTemplate: MoleculeListTemplate { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- public var closeButton: Button? @@ -17,5 +20,8 @@ open class ModalMoleculeListTemplate: MoleculeListTemplate { closeButton = MVMCoreUICommonViewsUtility.addCloseButton(to: view, action: { _ in MVMCoreNavigationHandler.shared()?.removeCurrentViewController() }) + + accessibilityElements = [closeButton as Any, tableView as Any] + UIAccessibility.post(notification: .layoutChanged, argument: closeButton) } } diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListCellProtocol.swift b/MVMCoreUI/Atomic/Templates/MoleculeListCellProtocol.swift index b9cfc02f..46c9a0fa 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListCellProtocol.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListCellProtocol.swift @@ -21,12 +21,10 @@ public protocol MoleculeListCellProtocol: UITableViewCell { // Default implementation does nothing extension MoleculeListCellProtocol { - public func setLines(with model: LineModel?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?, indexPath: IndexPath) { - } - public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - } - - func willDisplay() { - } + public func setLines(with model: LineModel?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?, indexPath: IndexPath) { } + + public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { } + + func willDisplay() { } } diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift index 09ca1b41..521a0d45 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift @@ -209,8 +209,11 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol func getMoleculeInfo(with listItem: (ListItemModelProtocol & MoleculeModelProtocol)?) -> (identifier: String, class: AnyClass, molecule: ListItemModelProtocol & MoleculeModelProtocol)? { guard let listItem = listItem, - let moleculeClass = MoleculeObjectMapping.shared()?.getMoleculeClass(listItem) else { return nil } + let moleculeClass = MoleculeObjectMapping.shared()?.getMoleculeClass(listItem) + else { return nil } + let moleculeName = moleculeClass.nameForReuse(with: listItem, delegateObject() as? MVMCoreUIDelegateObject) ?? listItem.moleculeName + return (moleculeName, moleculeClass, listItem) } diff --git a/MVMCoreUI/Atomic/Templates/TemplateModel.swift b/MVMCoreUI/Atomic/Templates/TemplateModel.swift index 3dcf3964..e8992e58 100644 --- a/MVMCoreUI/Atomic/Templates/TemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/TemplateModel.swift @@ -28,6 +28,7 @@ import Foundation public var screenHeading: String? public var navigationItem: (NavigationItemModelProtocol & MoleculeModelProtocol)? public var formRules: [FormGroupRule]? + public var behaviors: [PageBehaviorProtocol]? //-------------------------------------------------- // MARK: - Initializer @@ -47,6 +48,7 @@ import Foundation case screenHeading case backgroundColor case formRules + case behaviors case navigationItem } @@ -60,6 +62,7 @@ import Foundation screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) formRules = try typeContainer.decodeIfPresent([FormGroupRule].self, forKey: .formRules) + behaviors = try typeContainer.decodeModelsIfPresent(codingKey: .behaviors) navigationItem = try typeContainer.decodeModelIfPresent(codingKey: .navigationItem) } diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift new file mode 100644 index 00000000..d750c79a --- /dev/null +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -0,0 +1,9 @@ +// +// BarButtonItem.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/18/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation diff --git a/MVMCoreUI/BaseClasses/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift index b549b6d0..f07b1ee2 100644 --- a/MVMCoreUI/BaseClasses/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -205,6 +205,8 @@ import UIKit let caret = CaretView(lineWidth: 1) caret.translatesAutoresizingMaskIntoConstraints = true caret.isAccessibilityElement = true + caret.accessibilityTraits = .button + caret.accessibilityLabel = "Caret," caret.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccTabHint") caret.size = .small(.vertical) if let size = caret.size?.dimensions() { diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index 191806bb..2c609e02 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -9,7 +9,7 @@ import UIKit -@objc open class TextView: UITextView, UITextViewDelegate, MVMCoreViewProtocol { +@objc open class TextView: UITextView, MVMCoreViewProtocol, MoleculeViewProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -19,87 +19,18 @@ import UIKit private var initialSetupPerformed = false /// If true then text textView is currently displaying the stored placeholder text as there is not content to display. - public var isShowingPlaceholder: Bool = false { - didSet { textViewModel?.showsPlaceholder = isShowingPlaceholder } - } + public var isShowingPlaceholder: Bool = false /// Set to true to hide the blinking textField cursor. public var hideBlinkingCaret = false - public var textViewModel: TextViewModel? { - return model as? TextViewModel - } + public var placeholder = "" + public var fontStyle: Styler.Font = Styler.Font.RegularBodyLarge + public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro + public var placeholderTextColor: UIColor = .mvmCoolGray3 - //-------------------------------------------------- - // MARK: - Drawing Properties - //-------------------------------------------------- - - private(set) var fieldState: FieldState = .original { - didSet (oldState) { - // Will not update if new state is the same as old. - if fieldState != oldState { - DispatchQueue.main.async { [weak self] in - guard let self = self else { return } - - self.fieldState.setStateUI(for: self) - } - } - } - } - - /// Determines if the top, left, and right borders should be drawn. - private var hideBorders = false - - public var borderStrokeColor: UIColor = .mvmCoolGray3 - public var bottomStrokeColor: UIColor = .mvmBlack - private var borderPath: UIBezierPath = UIBezierPath() - private var bottomPath: UIBezierPath = UIBezierPath() - - //-------------------------------------------------- - // MARK: - Property Observers - //-------------------------------------------------- - - private var _isEnabled: Bool = true - private var _showError: Bool = false - private var _isSelected: Bool = false - - public var isEnabled: Bool { - get { return _isEnabled } - set (enabled) { - - _isEnabled = enabled - _isSelected = false - _showError = false - - fieldState = enabled ? .original : .disabled - } - } - - public var showError: Bool { - get { return _showError } - set (error) { - - _showError = error - _isEnabled = true - _isSelected = false - - fieldState = error ? .error : .original - } - } - - public var isSelected: Bool { - get { return _isSelected } - set (selected) { - - _isSelected = selected - _isEnabled = true - - if _showError { - fieldState = selected ? .selectedError : .error - } else { - fieldState = selected ? .selected : .original - } - } + public var isEnabled: Bool = true { + didSet { isUserInteractionEnabled = isEnabled } } //-------------------------------------------------- @@ -109,26 +40,6 @@ import UIKit /// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well. public weak var didDeleteDelegate: TextInputDidDeleteProtocol? - /// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well. - private weak var proprietorTextDelegate: UITextViewDelegate? - - /// If you're using a ViewController, you must set this to it. - public weak var uiTextViewDelegate: UITextViewDelegate? { - get { return delegate } - set { - delegate = self - proprietorTextDelegate = newValue - } - } - - var delegateObject: MVMCoreUIDelegateObject? - - //-------------------------------------------------- - // MARK: - Constraint - //-------------------------------------------------- - - public var heightConstraint: NSLayoutConstraint? - //-------------------------------------------------- // MARK: - Initialization //-------------------------------------------------- @@ -147,11 +58,6 @@ import UIKit initialSetup() } - convenience init(delegate: UITextViewDelegate) { - self.init(frame: .zero, textContainer: nil) - self.delegate = delegate - } - //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- @@ -166,172 +72,53 @@ import UIKit } open func updateView(_ size: CGFloat) { - - setNeedsDisplay() + font = (isShowingPlaceholder ? placeholderFontStyle : fontStyle).getFont() } /// Will be called only once. open func setupView() { translatesAutoresizingMaskIntoConstraints = false - initialConfiguration() + defaultConfiguration() } - public func initialConfiguration() { + public func defaultConfiguration() { + text = "" + placeholder = "" + textAlignment = .left insetsLayoutMarginsFromSafeArea = false showsVerticalScrollIndicator = false showsHorizontalScrollIndicator = false isSecureTextEntry = false - textContainerInset = UIEdgeInsets(top: Padding.Three, left: Padding.Three, bottom: Padding.Three, right: Padding.Three) backgroundColor = .mvmWhite clipsToBounds = true smartQuotesType = .no smartDashesType = .no smartInsertDeleteType = .no inputAccessoryView = nil - font = textViewModel?.fontStyle.getFont() + isAccessibilityElement = true + accessibilityTraits = .staticText + font = fontStyle.getFont() + keyboardType = .default isEditable = true - isOpaque = false } open func reset() { + fontStyle = Styler.Font.RegularBodyLarge + placeholderFontStyle = Styler.Font.RegularMicro + placeholderTextColor = .mvmCoolGray3 + textColor = .mvmBlack + isEnabled = true text = "" + isShowingPlaceholder = false inputAccessoryView?.removeFromSuperview() - inputAccessoryView = nil - initialConfiguration() - } - - open override func layoutSubviews() { - super.layoutSubviews() - - setNeedsDisplay() + defaultConfiguration() } //-------------------------------------------------- - // MARK: - Draw - //-------------------------------------------------- - - /// This handles the top, left, and right border lines. - open override func draw(_ rect: CGRect) { - super.draw(rect) - - borderPath.removeAllPoints() - bottomPath.removeAllPoints() - - if !hideBorders { - // Brings the other half of the line inside the view to prevent line cropping. - let origin = bounds.origin - let size = frame.size - let insetLean: CGFloat = 0.5 - borderPath.lineWidth = 1 - - // Drawing begins and ends from the bottom left. - borderPath.move(to: CGPoint(x: origin.x + insetLean, y: origin.y + size.height)) - borderPath.addLine(to: CGPoint(x: origin.x + insetLean, y: origin.y + insetLean)) - borderPath.addLine(to: CGPoint(x: origin.x + size.width - insetLean, y: origin.y + insetLean)) - borderPath.addLine(to: CGPoint(x: origin.x + size.width - insetLean, y: origin.y + size.height)) - - borderStrokeColor.setStroke() - borderPath.stroke() - - let lineWidth: CGFloat = showError || isSelected ? 4 : 1 - bottomPath.lineWidth = lineWidth - bottomPath.move(to: CGPoint(x: origin.x + size.width, y: origin.y + size.height - (lineWidth / 2))) - bottomPath.addLine(to: CGPoint(x: origin.x, y: origin.y + size.height - (lineWidth / 2))) - - bottomStrokeColor.setStroke() - bottomPath.stroke() - } - } - - //-------------------------------------------------- - // MARK: - Draw States - //-------------------------------------------------- - - public enum FieldState { - case original - case error - case selectedError - case selected - case disabled - - public func setStateUI(for inputField: TextView) { - - switch self { - case .original: - inputField.originalUI() - - case .error: - inputField.errorUI() - - case .selectedError: - inputField.selectedErrorUI() - - case .selected: - inputField.selectedUI() - - case .disabled: - inputField.disabledUI() - } - - inputField.setNeedsDisplay() - } - } - - open func originalUI() { - - isEditable = textViewModel?.editable ?? true - isUserInteractionEnabled = true - hideBorders = textViewModel?.hideBorders ?? false - borderStrokeColor = .mvmCoolGray3 - bottomStrokeColor = .mvmBlack - textColor = isShowingPlaceholder ? textViewModel?.placeholderTextColor.uiColor : textViewModel?.enabledTextColor.uiColor - } - - open func errorUI() { - - isEditable = textViewModel?.editable ?? true - isUserInteractionEnabled = true - hideBorders = textViewModel?.hideBorders ?? false - borderStrokeColor = .mvmOrange - bottomStrokeColor = .mvmOrange - textColor = textViewModel?.enabledTextColor.uiColor - } - - open func selectedErrorUI() { - - isEditable = textViewModel?.editable ?? true - isUserInteractionEnabled = true - hideBorders = textViewModel?.hideBorders ?? false - borderStrokeColor = .mvmBlack - bottomStrokeColor = .mvmOrange - textColor = textViewModel?.enabledTextColor.uiColor - } - - open func selectedUI() { - - isEditable = textViewModel?.editable ?? true - isUserInteractionEnabled = true - hideBorders = textViewModel?.hideBorders ?? false - borderStrokeColor = .mvmBlack - bottomStrokeColor = .mvmBlack - textColor = textViewModel?.enabledTextColor.uiColor - } - - open func disabledUI() { - - isEditable = textViewModel?.editable ?? false - isUserInteractionEnabled = false - hideBorders = textViewModel?.hideBorders ?? false - borderStrokeColor = .mvmCoolGray3 - bottomStrokeColor = .mvmCoolGray3 - textColor = textViewModel?.disabledTextColor.uiColor - } - - //-------------------------------------------------- - // MARK: - Methods + // MARK: - TextInputDidDeleteProtocol //-------------------------------------------------- /// Alters the blinking caret line as per design standards. @@ -350,141 +137,49 @@ import UIKit didDeleteDelegate?.textInputDidDelete() } - public func setTextAppearance() { + //-------------------------------------------------- + // MARK: - Text / Placeholder + //-------------------------------------------------- + + open override func becomeFirstResponder() -> Bool { if isShowingPlaceholder { setTextContentTraits() } + return super.becomeFirstResponder() + } + + open override func resignFirstResponder() -> Bool { + + setPlaceholderIfAvailable() + return super.resignFirstResponder() } public func setPlaceholderIfAvailable() { - if let placeholder = textViewModel?.placeholder, !placeholder.isEmpty && text.isEmpty { + if !placeholder.isEmpty && text.isEmpty { setPlaceholderContentTraits() } } - public func setTextContentTraits() { + open func setTextContentTraits() { isShowingPlaceholder = false text = "" - font = textViewModel?.fontStyle.getFont() - textColor = textViewModel?.enabledTextColor.uiColor + font = fontStyle.getFont() + textColor = .mvmBlack } - public func setPlaceholderContentTraits() { + open func setPlaceholderContentTraits() { isShowingPlaceholder = true - textColor = textViewModel?.placeholderTextColor.uiColor - font = textViewModel?.placeholderFontStyle.getFont() - text = textViewModel?.placeholder + textColor = placeholderTextColor + font = placeholderFontStyle.getFont() + text = placeholder } - @objc func dismissFieldInput(_ sender: TextView) { + @objc open func dismissFieldInput(_ sender: TextView) { - resignFirstResponder() - } - - //-------------------------------------------------- - // MARK: - UITextViewDelegate - //-------------------------------------------------- - - @objc public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool { - - return proprietorTextDelegate?.textViewShouldBeginEditing?(textView) ?? true - } - - @objc public func textViewDidBeginEditing(_ textView: UITextView) { - - setTextAppearance() - isSelected = true - proprietorTextDelegate?.textViewDidBeginEditing?(textView) - } - - @objc public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { - - return proprietorTextDelegate?.textView?(textView, shouldChangeTextIn: range, replacementText: text) ?? true - } - - @objc public func textViewDidChange(_ textView: UITextView) { - - textViewModel?.text = textView.text - proprietorTextDelegate?.textViewDidChange?(textView) - } - - @objc public func textViewShouldEndEditing(_ textView: UITextView) -> Bool { - - return proprietorTextDelegate?.textViewShouldEndEditing?(textView) ?? true - } - - @objc public func textViewDidEndEditing(_ textView: UITextView) { - - setPlaceholderIfAvailable() - isSelected = false - proprietorTextDelegate?.textViewDidEndEditing?(textView) - } -} - -// MARK:- MoleculeViewProtocol -extension TextView: MoleculeViewProtocol { - - open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - self.model = model - self.delegateObject = delegateObject - - if let color = model.backgroundColor?.uiColor { - backgroundColor = color - } - - guard let model = model as? TextViewModel else { return } - - heightConstraint?.isActive = false - if let height = model.height { - heightConstraint = heightAnchor.constraint(equalToConstant: height) - heightConstraint?.isActive = true - } - - isEditable = model.editable - textAlignment = model.textAlignment - textColor = model.enabledTextColor.uiColor - hideBorders = model.hideBorders - text = model.text - uiTextViewDelegate = delegateObject?.uiTextViewDelegate - - if let accessibilityText = model.accessibilityText { - accessibilityLabel = accessibilityText - } - - switch model.type { - case .secure, .password: - isSecureTextEntry = true - case .number: - keyboardType = .numberPad - case .email: - keyboardType = .emailAddress - default: - break - } - - font = model.fontStyle.getFont() - setPlaceholderIfAvailable() - - if isEditable { - FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) - let observingDelegate = delegateObject?.uiTextViewDelegate ?? self - inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate, - action: #selector(dismissFieldInput)) - - if (model.selected ?? false) && !model.wasInitiallySelected { - model.wasInitiallySelected = true - DispatchQueue.main.async { - self.becomeFirstResponder() - } - } - } - - if !model.enabled { - isEnabled = false - } + _ = resignFirstResponder() } } diff --git a/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift b/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift index d6851d78..64242fc3 100644 --- a/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift +++ b/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift @@ -9,6 +9,6 @@ import Foundation -public protocol MVMControllerModelProtocol: TemplateModelProtocol, FormHolderModelProtocol { +public protocol MVMControllerModelProtocol: TemplateModelProtocol, FormHolderModelProtocol, PageBehaviorsTemplateProtocol { } diff --git a/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift b/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift index 8e01cf6c..7962dcf5 100644 --- a/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift +++ b/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift @@ -40,6 +40,7 @@ open class ThreeLayerTableViewController: ProgrammaticTableViewController { createViewForTableHeader() createViewForTableFooter() tableView?.reloadData() + accessibilityElements = [tableView as Any] } override open func viewDidLoad() { diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 315a0476..c44a8d47 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -17,7 +17,10 @@ import UIKit public var manager: (UIViewController & MVMCoreViewManagerProtocol)? /// A temporary iVar backer for delegateObject() until we change the protocol - public var delegateObjectIVar: MVMCoreUIDelegateObject? + public lazy var delegateObjectIVar: MVMCoreUIDelegateObject = { + return MVMCoreUIDelegateObject.create(withDelegateForAll: self) + }() + public func delegateObject() -> DelegateObject? { return delegateObjectIVar } @@ -264,9 +267,6 @@ import UIKit // Presents from the bottom. modalPresentationStyle = MVMCoreGetterUtility.isOnIPad() ? .formSheet : .overCurrentContext - // Create the default delegate object. - delegateObjectIVar = MVMCoreUIDelegateObject.create(withDelegateForAll: self) - // Do some initial loading. if !initialLoadFinished { initialLoadFinished = true @@ -310,6 +310,18 @@ import UIKit MVMCoreUISession.sharedGlobal()?.currentPageType = pageType MVMCoreUILoggingHandler.shared()?.defaultLogPageState(forController: self) } + + executeBehaviors { (behavior: PageVisibilityBehavior) in + behavior.onPageShown() + } + } + + open override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + + executeBehaviors { (behavior: PageVisibilityBehavior) in + behavior.onPageHidden() + } } deinit { @@ -424,4 +436,9 @@ import UIKit selectedField = nil } } + + // MARK: - Behavior Execution + func executeBehaviors(_ behaviorBlock:(_ behavior:T)->Void) { + pageModel?.behaviors?.compactMap({ $0 as? T }).forEach({ behaviorBlock($0) }) + } } diff --git a/MVMCoreUI/Behaviors/PageBehavior.swift b/MVMCoreUI/Behaviors/PageBehavior.swift new file mode 100644 index 00000000..d8fd99a3 --- /dev/null +++ b/MVMCoreUI/Behaviors/PageBehavior.swift @@ -0,0 +1,44 @@ +// +// PageBehaviors.swift +// MVMCoreUI +// +// Created by Kyle on 5/8/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol PageBehaviorProtocol: ModelProtocol { + + // The type of rule + var behaviorName: String { get } + +} + +public extension PageBehaviorProtocol { + + var behaviorName: String { + get { return Self.identifier } + } + + static var categoryCodingKey: String { + return "behaviorName" + } + + static var categoryName: String { + return "\(PageBehaviorProtocol.self)" + } +} + +public protocol PageVisibilityBehavior: PageBehaviorProtocol { + + func onPageShown() + func onPageHidden() + +} + +public protocol PageBehaviorsTemplateProtocol { + + var behaviors: [PageBehaviorProtocol]? { get } + +} diff --git a/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift b/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift new file mode 100644 index 00000000..b6ea9f6d --- /dev/null +++ b/MVMCoreUI/Behaviors/ScreenBrightnessModifierBehavior.swift @@ -0,0 +1,68 @@ +// +// ScreenBrightnessModifierBehavior.swift +// MVMCoreUI +// +// Created by Kyle on 5/9/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +public class ScreenBrightnessModifierBehavior: PageVisibilityBehavior { + + public static var identifier = "screenBrightnessModifier" + + @Clamping(range: 0...1) var screenBrightness: CGFloat + + var originalScreenBrightness: CGFloat? + + //MARK:- PageVisibilityBehavior + + public func onPageShown() { + changeScreenBrightness() + } + + public func onPageHidden() { + restoreScreenBrightness() + } + + //MARK:- Behavior + + func changeScreenBrightness() { + guard originalScreenBrightness == nil else { return } + originalScreenBrightness = UIScreen.main.brightness + UIScreen.main.brightness = screenBrightness + NotificationCenter.default.addObserver(self, selector: #selector(willResignActive), name: UIApplication.willResignActiveNotification, object: nil) + } + + func restoreScreenBrightness() { + guard let originalScreenBrightness = originalScreenBrightness else { return } + UIScreen.main.brightness = originalScreenBrightness + self.originalScreenBrightness = nil + NotificationCenter.default.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil) + } + + @objc func willResignActive() { + restoreScreenBrightness() + NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil) + } + + @objc func didBecomeActive() { + NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil) + changeScreenBrightness() + } + + //MARK:- Codable + + private enum CodingKeys: String, CodingKey { + case screenBrightness + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + screenBrightness = try typeContainer.decode(CGFloat.self, forKey: .screenBrightness) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(screenBrightness, forKey: .screenBrightness) + } +} diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 3497075f..4150da12 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -57,7 +57,7 @@ import UIKit // Update line. if let navigationController = navigationController as? NavigationController { - navigationController.separatorView?.setStyle(navigationItemModel.line?.type ?? .standard) + navigationController.separatorView?.isHidden = navigationItemModel.line?.type ?? .standard == .none } // Update icons if main navigation controller. diff --git a/MVMCoreUI/Containers/Views/ContainerHelper.swift b/MVMCoreUI/Containers/Views/ContainerHelper.swift index 4ce97f5c..f60d1ee6 100644 --- a/MVMCoreUI/Containers/Views/ContainerHelper.swift +++ b/MVMCoreUI/Containers/Views/ContainerHelper.swift @@ -9,7 +9,12 @@ import Foundation + open class ContainerHelper: NSObject { + //-------------------------------------------------- + // MARK: - Constraints + //-------------------------------------------------- + var leftConstraint: NSLayoutConstraint? var topConstraint: NSLayoutConstraint? var bottomConstraint: NSLayoutConstraint? @@ -28,17 +33,26 @@ open class ContainerHelper: NSObject { var bottomLowConstraint: NSLayoutConstraint? var rightLowConstraint: NSLayoutConstraint? + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + open func constrainView(_ view: UIView) { guard let margins = view.superview?.layoutMarginsGuide else { return } + + leftConstraint?.isActive = false leftConstraint = view.leftAnchor.constraint(equalTo: margins.leftAnchor) leftConstraint?.isActive = true + topConstraint?.isActive = false topConstraint = view.topAnchor.constraint(equalTo: margins.topAnchor) topConstraint?.isActive = true + rightConstraint?.isActive = false rightConstraint = margins.rightAnchor.constraint(equalTo: view.rightAnchor) rightConstraint?.isActive = true + bottomConstraint?.isActive = false bottomConstraint = margins.bottomAnchor.constraint(equalTo: view.bottomAnchor) bottomConstraint?.isActive = true @@ -50,23 +64,25 @@ open class ContainerHelper: NSObject { alignCenterTopConstraint = view.topAnchor.constraint(greaterThanOrEqualTo: margins.topAnchor) alignCenterBottomConstraint = margins.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor) + leftLowConstraint?.isActive = false leftLowConstraint = view.leftAnchor.constraint(equalTo: margins.leftAnchor) leftLowConstraint?.priority = UILayoutPriority(rawValue: 200) leftLowConstraint?.isActive = true + topLowConstraint?.isActive = false topLowConstraint = view.topAnchor.constraint(equalTo: margins.topAnchor) topLowConstraint?.priority = UILayoutPriority(rawValue: 200) topLowConstraint?.isActive = true + rightLowConstraint?.isActive = false rightLowConstraint = margins.rightAnchor.constraint(equalTo: view.rightAnchor) rightLowConstraint?.priority = UILayoutPriority(rawValue: 200) rightLowConstraint?.isActive = true + bottomLowConstraint?.isActive = false bottomLowConstraint = margins.bottomAnchor.constraint(equalTo: view.bottomAnchor) bottomLowConstraint?.priority = UILayoutPriority(rawValue: 200) bottomLowConstraint?.isActive = true - - setAccessibility(view) } open func setAccessibility(_ view: UIView) { diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAllValueChangedModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAllValueChangedModel.swift index 1f50bcc7..aa80f5b0 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAllValueChangedModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAllValueChangedModel.swift @@ -15,6 +15,7 @@ public class RuleAllValueChangedModel: RulesProtocol { public static var identifier: String = "allValueChanged" public var type: String = RuleAllValueChangedModel.identifier + public var errorMessage: [String: String]? public var fields: [String] //-------------------------------------------------- diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyRequiredModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyRequiredModel.swift index 6ca905bf..7f153e83 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyRequiredModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyRequiredModel.swift @@ -17,6 +17,7 @@ public class RuleAnyRequiredModel: RulesProtocol { public static var identifier: String = "anyRequired" public var type: String = RuleRequiredModel.identifier public var fields: [String] + public var errorMessage: [String: String]? //-------------------------------------------------- // MARK: - Methods diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyValueChangedModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyValueChangedModel.swift index 450fdb2a..07cf451f 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyValueChangedModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyValueChangedModel.swift @@ -16,6 +16,7 @@ public class RuleAnyValueChangedModel: RulesProtocol { public static var identifier: String = "anyValueChanged" public var type: String = RuleAnyValueChangedModel.identifier + public var errorMessage: [String: String]? public var fields: [String] //-------------------------------------------------- diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift new file mode 100644 index 00000000..0bdd7ca3 --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsIgnoreCaseModel.swift @@ -0,0 +1,52 @@ +// +// RuleEqualsIgnoreCaseModel.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 5/15/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + + +public class RuleEqualsIgnoreCaseModel: RulesProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public static var identifier: String = "equalsIgnoreCase" + public var type: String = RuleEqualsIgnoreCaseModel.identifier + public var fields: [String] + public var errorMessage: [String: String]? + + //-------------------------------------------------- + // MARK: - Validation + //-------------------------------------------------- + + public func isValid(_ formField: FormFieldProtocol) -> Bool { + return false + } + + public func validate(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool { + var valid = false + var compareText: String? + + for formKey in fields { + guard let formField = fieldMolecules[formKey] else { continue } + + guard let compareString = compareText else { + compareText = formField.formFieldValue() as? String + continue + } + + if let fieldValue = formField.formFieldValue() as? String, + compareString.caseInsensitiveCompare(fieldValue) == .orderedSame { + valid = true + } + + (formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self) + } + + return valid + } +} diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift index fb7585f2..fa73ed51 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift @@ -17,6 +17,7 @@ public class RuleEqualsModel: RulesProtocol { public static var identifier: String = "equals" public var type: String = RuleEqualsModel.identifier public var fields: [String] + public var errorMessage: [String: String]? //-------------------------------------------------- // MARK: - Validation @@ -27,9 +28,9 @@ public class RuleEqualsModel: RulesProtocol { } public func validate(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool { - var valid = true - var compareValue: AnyHashable? - + var valid = true + var compareValue: AnyHashable? + for formKey in fields { guard let formField = fieldMolecules[formKey] else { continue } @@ -37,13 +38,16 @@ public class RuleEqualsModel: RulesProtocol { compareValue = formField.formFieldValue() continue } - + if compareValue != formField.formFieldValue() { valid = false + (formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self) break + } else { + (formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self) } } - - return valid + + return valid } } diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift index 68eea7e5..5f60a61b 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift @@ -18,6 +18,7 @@ public class RuleRegexModel: RulesProtocol { public var type: String = RuleRegexModel.identifier public var fields: [String] public var regex: String + public var errorMessage: [String: String]? //-------------------------------------------------- // MARK: - Properties diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift index b34a24df..77cdf254 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift @@ -16,6 +16,7 @@ public class RuleRequiredModel: RulesProtocol { public static var identifier: String = "allRequired" public var type: String = RuleRequiredModel.identifier + public var errorMessage: [String: String]? public var fields: [String] //-------------------------------------------------- @@ -23,6 +24,7 @@ public class RuleRequiredModel: RulesProtocol { //-------------------------------------------------- public func isValid(_ formField: FormFieldProtocol) -> Bool { + guard let value = formField.formFieldValue() else { return false } var valid = true diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RulesProtocol.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RulesProtocol.swift index 305b4c35..7392ea8f 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RulesProtocol.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RulesProtocol.swift @@ -16,7 +16,9 @@ public enum RulesCodingKey: String, CodingKey { public protocol RulesProtocol: ModelProtocol { // The type of rule var type: String { get } - + + var errorMessage: [String: String]? { get } + // The fields that this rule applies to. var fields: [String] { get set } 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/Strings/en.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings index 25dd849b..da55d597 100644 --- a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings @@ -53,6 +53,7 @@ // MARK: Radio Button +"radio_button" = "Radio Button,"; "radio_action_hint" = "Double tap to select"; "radio_selected_state" = "Selected"; "radio_not_selected_state" = "Not Selected"; diff --git a/MVMCoreUI/Utility/MFFonts.h b/MVMCoreUI/Utility/MFFonts.h index fb4bbe92..46947581 100644 --- a/MVMCoreUI/Utility/MFFonts.h +++ b/MVMCoreUI/Utility/MFFonts.h @@ -14,9 +14,6 @@ extern NSString * _Nonnull const DSBold; extern NSString * _Nonnull const DSRegular; extern NSString * _Nonnull const TXBold; extern NSString * _Nonnull const TXRegular; -//2.0 font -extern NSString * _Nonnull const DS75Bd; -extern NSString * _Nonnull const DS55Rg; @interface MFFonts : NSObject diff --git a/MVMCoreUI/Utility/MFFonts.m b/MVMCoreUI/Utility/MFFonts.m index 150cffa7..d16f15ec 100644 --- a/MVMCoreUI/Utility/MFFonts.m +++ b/MVMCoreUI/Utility/MFFonts.m @@ -17,11 +17,6 @@ NSString * const DSRegular = @"VerizonNHGeDS-Regular"; NSString * const TXBold = @"VerizonNHGeTX-Bold"; NSString * const TXRegular = @"VerizonNHGeTX-Regular"; -//2.0 font -NSString * const DS75Bd = @"NHaasGroteskDSStd-75Bd"; -NSString * const DS55Rg = @"NHaasGroteskDSStd-55Rg"; - - @implementation MFFonts + (void)loadMVMFonts { @@ -31,8 +26,6 @@ NSString * const DS55Rg = @"NHaasGroteskDSStd-55Rg"; [MFFonts loadFont:DSRegular type:@"otf"]; [MFFonts loadFont:TXBold type:@"otf"]; [MFFonts loadFont:TXRegular type:@"otf"]; - [MFFonts loadFont:DS75Bd type:@"otf"]; - [MFFonts loadFont:DS55Rg type:@"otf"]; [MFFonts loadFont:@"OCRAExtended" type:@"ttf"]; }); }