Merge branch 'develop' into feature/order_tracker

This commit is contained in:
Kevin G Christiano 2020-07-08 10:21:55 -04:00
commit b546588665
86 changed files with 1527 additions and 198 deletions

View File

@ -74,6 +74,8 @@
0A25209824645B76000FA9F6 /* TextViewEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A25209724645B76000FA9F6 /* TextViewEntryFieldModel.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 */; }; 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; };
0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */; }; 0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */; };
0A51F3E22475CB73002E08B6 /* LoadingSpinnerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A51F3E02475CB73002E08B6 /* LoadingSpinnerModel.swift */; };
0A51F3E32475CB73002E08B6 /* LoadingSpinner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A51F3E12475CB73002E08B6 /* LoadingSpinner.swift */; };
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */; }; 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */; };
0A6682A22434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */; }; 0A6682A22434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */; };
0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */; }; 0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */; };
@ -82,6 +84,7 @@
0A6682B5243769C700AD3CA1 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682B3243769C700AD3CA1 /* TextView.swift */; }; 0A6682B5243769C700AD3CA1 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682B3243769C700AD3CA1 /* TextView.swift */; };
0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */; }; 0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */; };
0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; }; 0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; };
0A6C1FC324927E2E00E64B52 /* colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0A6C1FC224927E2E00E64B52 /* colors.xcassets */; };
0A775F2624893916009EFB58 /* ThreeHeadlineBodyLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A775F2524893916009EFB58 /* ThreeHeadlineBodyLink.swift */; }; 0A775F2624893916009EFB58 /* ThreeHeadlineBodyLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A775F2524893916009EFB58 /* ThreeHeadlineBodyLink.swift */; };
0A775F2824893937009EFB58 /* ThreeHeadlineBodyLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A775F2724893937009EFB58 /* ThreeHeadlineBodyLinkModel.swift */; }; 0A775F2824893937009EFB58 /* ThreeHeadlineBodyLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A775F2724893937009EFB58 /* ThreeHeadlineBodyLinkModel.swift */; };
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; }; 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; };
@ -230,6 +233,8 @@
AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; }; AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; };
AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatch.swift */; }; AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatch.swift */; };
AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; }; AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; };
AAE7270C24AC8B8500A3ED0E /* HeadersH2CaretLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE7270B24AC8B8500A3ED0E /* HeadersH2CaretLinkModel.swift */; };
AAE7270E24AC8B9300A3ED0E /* HeadersH2CaretLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE7270D24AC8B9300A3ED0E /* HeadersH2CaretLink.swift */; };
BB105859248DEFF70069D008 /* UICollectionViewLeftAlignedLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */; }; BB105859248DEFF70069D008 /* UICollectionViewLeftAlignedLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */; };
BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */; }; BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */; };
BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */; }; BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */; };
@ -533,6 +538,8 @@
0A25209724645B76000FA9F6 /* TextViewEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewEntryFieldModel.swift; sourceTree = "<group>"; }; 0A25209724645B76000FA9F6 /* TextViewEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewEntryFieldModel.swift; sourceTree = "<group>"; };
0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CATransaction+Extension.swift"; sourceTree = "<group>"; }; 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CATransaction+Extension.swift"; sourceTree = "<group>"; };
0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = "<group>"; }; 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = "<group>"; };
0A51F3E02475CB73002E08B6 /* LoadingSpinnerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadingSpinnerModel.swift; sourceTree = "<group>"; };
0A51F3E12475CB73002E08B6 /* LoadingSpinner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadingSpinner.swift; sourceTree = "<group>"; };
0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleGuidelinesProtocol.swift; sourceTree = "<group>"; }; 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleGuidelinesProtocol.swift; sourceTree = "<group>"; };
0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonBodyText.swift; sourceTree = "<group>"; }; 0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonBodyText.swift; sourceTree = "<group>"; };
0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonBodyTextModel.swift; sourceTree = "<group>"; }; 0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonBodyTextModel.swift; sourceTree = "<group>"; };
@ -541,6 +548,7 @@
0A6682B3243769C700AD3CA1 /* TextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = "<group>"; }; 0A6682B3243769C700AD3CA1 /* TextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = "<group>"; };
0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyRequiredModel.swift; sourceTree = "<group>"; }; 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyRequiredModel.swift; sourceTree = "<group>"; };
0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseDropdownEntryField.swift; sourceTree = "<group>"; }; 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseDropdownEntryField.swift; sourceTree = "<group>"; };
0A6C1FC224927E2E00E64B52 /* colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = colors.xcassets; path = MVMCoreUI/Categories/colors.xcassets; sourceTree = SOURCE_ROOT; };
0A775F2524893916009EFB58 /* ThreeHeadlineBodyLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeHeadlineBodyLink.swift; sourceTree = "<group>"; }; 0A775F2524893916009EFB58 /* ThreeHeadlineBodyLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeHeadlineBodyLink.swift; sourceTree = "<group>"; };
0A775F2724893937009EFB58 /* ThreeHeadlineBodyLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeHeadlineBodyLinkModel.swift; sourceTree = "<group>"; }; 0A775F2724893937009EFB58 /* ThreeHeadlineBodyLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeHeadlineBodyLinkModel.swift; sourceTree = "<group>"; };
0A7918F423F5E7EA00772FF4 /* ImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageView.swift; sourceTree = "<group>"; }; 0A7918F423F5E7EA00772FF4 /* ImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageView.swift; sourceTree = "<group>"; };
@ -692,6 +700,8 @@
AAB9C10724346F4B00151545 /* RadioSwatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatches.swift; sourceTree = "<group>"; }; AAB9C10724346F4B00151545 /* RadioSwatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatches.swift; sourceTree = "<group>"; };
AAB9C109243496DD00151545 /* RadioSwatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatch.swift; sourceTree = "<group>"; }; AAB9C109243496DD00151545 /* RadioSwatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatch.swift; sourceTree = "<group>"; };
AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.swift; sourceTree = "<group>"; }; AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.swift; sourceTree = "<group>"; };
AAE7270B24AC8B8500A3ED0E /* HeadersH2CaretLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2CaretLinkModel.swift; sourceTree = "<group>"; };
AAE7270D24AC8B9300A3ED0E /* HeadersH2CaretLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2CaretLink.swift; sourceTree = "<group>"; };
BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewLeftAlignedLayout.swift; sourceTree = "<group>"; }; BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewLeftAlignedLayout.swift; sourceTree = "<group>"; };
BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMediumModel.swift; sourceTree = "<group>"; }; BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMediumModel.swift; sourceTree = "<group>"; };
BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMedium.swift; sourceTree = "<group>"; }; BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMedium.swift; sourceTree = "<group>"; };
@ -1552,6 +1562,8 @@
AA633B3224989ED500731E80 /* HeadersH2PricingTwoRows.swift */, AA633B3224989ED500731E80 /* HeadersH2PricingTwoRows.swift */,
AA71AD3D24A32FCE00ACA76F /* HeadersH2LinkModel.swift */, AA71AD3D24A32FCE00ACA76F /* HeadersH2LinkModel.swift */,
AA71AD3F24A32FE700ACA76F /* HeadersH2Link.swift */, AA71AD3F24A32FE700ACA76F /* HeadersH2Link.swift */,
AAE7270B24AC8B8500A3ED0E /* HeadersH2CaretLinkModel.swift */,
AAE7270D24AC8B9300A3ED0E /* HeadersH2CaretLink.swift */,
); );
path = H2; path = H2;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1810,6 +1822,8 @@
94382085243238D100B43AF3 /* WebViewModel.swift */, 94382085243238D100B43AF3 /* WebViewModel.swift */,
943820832432382400B43AF3 /* WebView.swift */, 943820832432382400B43AF3 /* WebView.swift */,
D20492A524329CE200A5EED6 /* LoadImageView.swift */, D20492A524329CE200A5EED6 /* LoadImageView.swift */,
0A51F3E02475CB73002E08B6 /* LoadingSpinnerModel.swift */,
0A51F3E12475CB73002E08B6 /* LoadingSpinner.swift */,
); );
path = Views; path = Views;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1894,6 +1908,7 @@
D29DF26621E6A9E4003B2FB9 /* ThirdParty */, D29DF26621E6A9E4003B2FB9 /* ThirdParty */,
D29DF31521ECECC0003B2FB9 /* Fonts */, D29DF31521ECECC0003B2FB9 /* Fonts */,
D29DF32D21EE8C3D003B2FB9 /* Media.xcassets */, D29DF32D21EE8C3D003B2FB9 /* Media.xcassets */,
0A6C1FC224927E2E00E64B52 /* colors.xcassets */,
); );
path = SupportingFiles; path = SupportingFiles;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2112,6 +2127,7 @@
files = ( files = (
94CA227C24058534002D6750 /* VerizonNHGeTX-Bold.otf in Resources */, 94CA227C24058534002D6750 /* VerizonNHGeTX-Bold.otf in Resources */,
D29DF32C21EE8736003B2FB9 /* Localizable.strings in Resources */, D29DF32C21EE8736003B2FB9 /* Localizable.strings in Resources */,
0A6C1FC324927E2E00E64B52 /* colors.xcassets in Resources */,
94CA227D24058534002D6750 /* VerizonNHGeDS-Regular.otf in Resources */, 94CA227D24058534002D6750 /* VerizonNHGeDS-Regular.otf in Resources */,
D29DF32E21EE8C3D003B2FB9 /* Media.xcassets in Resources */, D29DF32E21EE8C3D003B2FB9 /* Media.xcassets in Resources */,
94CA227E24058534002D6750 /* VerizonNHGeDS-Bold.otf in Resources */, 94CA227E24058534002D6750 /* VerizonNHGeDS-Bold.otf in Resources */,
@ -2395,6 +2411,7 @@
279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */, 279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */,
BB6C6AC0242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift in Sources */, BB6C6AC0242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift in Sources */,
8DEFA95E243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift in Sources */, 8DEFA95E243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift in Sources */,
AAE7270E24AC8B9300A3ED0E /* HeadersH2CaretLink.swift in Sources */,
D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */, D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */,
324FB6AC24936717002552C7 /* ListLeftVariableNumberedListBodyText.swift in Sources */, 324FB6AC24936717002552C7 /* ListLeftVariableNumberedListBodyText.swift in Sources */,
AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */, AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */,
@ -2426,6 +2443,7 @@
012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */, 012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */,
D2092355244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift in Sources */, D2092355244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift in Sources */,
0AE14F64238315D2005417F8 /* TextField.swift in Sources */, 0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
0A51F3E22475CB73002E08B6 /* LoadingSpinnerModel.swift in Sources */,
0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */, 0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */,
BB105859248DEFF70069D008 /* UICollectionViewLeftAlignedLayout.swift in Sources */, BB105859248DEFF70069D008 /* UICollectionViewLeftAlignedLayout.swift in Sources */,
D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */, D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */,
@ -2455,6 +2473,7 @@
0A21DB83235DFBC500C160A2 /* MdnEntryField.swift in Sources */, 0A21DB83235DFBC500C160A2 /* MdnEntryField.swift in Sources */,
0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */, 0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */,
D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */, D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */,
0A51F3E32475CB73002E08B6 /* LoadingSpinner.swift in Sources */,
BB2FB3BB247E7EBC00DF73CD /* TagCollectionViewCell.swift in Sources */, BB2FB3BB247E7EBC00DF73CD /* TagCollectionViewCell.swift in Sources */,
012A88C6238DA34000FE3DA1 /* ModuleMoleculeModel.swift in Sources */, 012A88C6238DA34000FE3DA1 /* ModuleMoleculeModel.swift in Sources */,
94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */, 94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */,
@ -2496,6 +2515,7 @@
D264FA90243BCE6800D98315 /* ThreeLayerCollectionViewController.swift in Sources */, D264FA90243BCE6800D98315 /* ThreeLayerCollectionViewController.swift in Sources */,
AA104B1C24474A76004D2810 /* HeadersH2ButtonsModel.swift in Sources */, AA104B1C24474A76004D2810 /* HeadersH2ButtonsModel.swift in Sources */,
0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */, 0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */,
AAE7270C24AC8B8500A3ED0E /* HeadersH2CaretLinkModel.swift in Sources */,
BB6C6AC824225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift in Sources */, BB6C6AC824225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift in Sources */,
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */, 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */,
D21B7F73243BAC6800051ABF /* CollectionItemModelProtocol.swift in Sources */, D21B7F73243BAC6800051ABF /* CollectionItemModelProtocol.swift in Sources */,

View File

@ -25,12 +25,9 @@ import UIKit
if numberOfDigits > 0 { if numberOfDigits > 0 {
var digitBoxes = [DigitBox]() var digitBoxes = [DigitBox]()
let ordinalFormatter = NumberFormatter()
ordinalFormatter.numberStyle = .ordinal
for i in 0..<numberOfDigits { for i in 0..<numberOfDigits {
let newDigitBox = createDigitField() let newDigitBox = createDigitField()
let accessibileLabel = ordinalFormatter.string(from: NSNumber(value: i + 1)) ?? "" let accessibileLabel = MVMCoreUIUtility.getOrdinalString(forIndex: NSNumber(value: i + 1)) ?? ""
newDigitBox.digitField.accessibilityLabel = "\(accessibileLabel) field of \(numberOfDigits) digit fields" newDigitBox.digitField.accessibilityLabel = "\(accessibileLabel) field of \(numberOfDigits) digit fields"
digitBoxes.append(newDigitBox) digitBoxes.append(newDigitBox)
} }

View File

@ -26,6 +26,18 @@ open class RadioBox: Control {
return model as? RadioBoxModel return model as? RadioBoxModel
} }
public override var isSelected: Bool {
didSet {
updateAccessibility()
}
}
public override var isEnabled: Bool {
didSet {
updateAccessibility()
}
}
// MARK: - MVMCoreViewProtocol // MARK: - MVMCoreViewProtocol
open override func updateView(_ size: CGFloat) { open override func updateView(_ size: CGFloat) {
@ -56,6 +68,8 @@ open class RadioBox: Control {
subTextLabelHeightConstraint?.isActive = true subTextLabelHeightConstraint?.isActive = true
addTarget(self, action: #selector(selectBox), for: .touchUpInside) addTarget(self, action: #selector(selectBox), for: .touchUpInside)
isAccessibilityElement = true
} }
// MARK: - MoleculeViewProtocol // MARK: - MoleculeViewProtocol
@ -63,8 +77,6 @@ open class RadioBox: Control {
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData) super.set(with: model, delegateObject, additionalData)
guard let model = model as? RadioBoxModel else { return } guard let model = model as? RadioBoxModel else { return }
isSelected = model.selected
isEnabled = model.enabled
label.text = model.text label.text = model.text
subTextLabel.text = model.subText subTextLabel.text = model.subText
isOutOfStock = model.strikethrough isOutOfStock = model.strikethrough
@ -72,6 +84,8 @@ open class RadioBox: Control {
if let color = model.selectedAccentColor?.uiColor { if let color = model.selectedAccentColor?.uiColor {
accentColor = color accentColor = color
} }
isSelected = model.selected
isEnabled = model.enabled
} }
open override func reset() { open override func reset() {
@ -91,7 +105,6 @@ open class RadioBox: Control {
strikeLayer = line strikeLayer = line
} }
// Draw the border // Draw the border
borderLayer?.removeFromSuperlayer() borderLayer?.removeFromSuperlayer()
if isSelected { if isSelected {
@ -191,5 +204,25 @@ open class RadioBox: Control {
mask.frame = bounds mask.frame = bounds
return mask return mask
} }
// MARK: - Accessibility
public func updateAccessibility() {
var message = ""
if let labelText = label.text, label.hasText {
message += labelText + ", "
}
if let subLabelText = subTextLabel.text, subTextLabel.hasText {
message += subLabelText + ", "
}
accessibilityLabel = message
accessibilityTraits = .button
if isSelected {
accessibilityTraits.insert(.selected)
}
if !isEnabled {
accessibilityTraits.insert(.notEnabled)
}
}
} }

View File

@ -17,6 +17,7 @@ open class RadioBoxCollectionViewCell: CollectionViewCell {
open override func setupView() { open override func setupView() {
super.setupView() super.setupView()
isAccessibilityElement = true
addMolecule(radioBox) addMolecule(radioBox)
MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0) MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0)
} }
@ -24,5 +25,12 @@ open class RadioBoxCollectionViewCell: CollectionViewCell {
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let model = model as? RadioBoxModel else { return } guard let model = model as? RadioBoxModel else { return }
radioBox.set(with: model, delegateObject, additionalData) radioBox.set(with: model, delegateObject, additionalData)
updateAccessibility()
}
open func updateAccessibility() {
accessibilityLabel = radioBox.accessibilityLabel
accessibilityHint = radioBox.accessibilityHint
accessibilityTraits = radioBox.accessibilityTraits
} }
} }

View File

@ -35,6 +35,13 @@ open class RadioBoxes: View {
} }
} }
open func updateAccessibilityValue(collectionView: UICollectionView, cell: RadioBoxCollectionViewCell, indexPath: IndexPath) {
guard let format = MVMCoreUIUtility.hardcodedString(withKey: "index_string_of_total"),
let indexString = MVMCoreUIUtility.getOrdinalString(forIndex: NSNumber(value: indexPath.row + 1)) else { return }
let total = self.collectionView(collectionView, numberOfItemsInSection: indexPath.section)
cell.accessibilityValue = String(format: format, indexString, total)
}
// MARK: - MVMCoreViewProtocol // MARK: - MVMCoreViewProtocol
open override func setupView() { open override func setupView() {
super.setupView() super.setupView()
@ -136,6 +143,7 @@ extension RadioBoxes: UICollectionViewDataSource {
if molecule.selected { if molecule.selected {
collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically) collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically)
} }
updateAccessibilityValue(collectionView: collectionView, cell: cell, indexPath: indexPath)
cell.layoutIfNeeded() cell.layoutIfNeeded()
return cell return cell
} }
@ -151,11 +159,13 @@ extension RadioBoxes: UICollectionViewDelegate {
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return } guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return }
cell.radioBox.selectBox() cell.radioBox.selectBox()
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
cell.updateAccessibility()
} }
open func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { open func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return } guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return }
cell.radioBox.deselectBox() cell.radioBox.deselectBox()
cell.updateAccessibility()
} }
} }

View File

@ -24,6 +24,18 @@ open class RadioSwatch: Control {
return model as? RadioSwatchModel return model as? RadioSwatchModel
} }
public override var isSelected: Bool {
didSet {
updateAccessibility()
}
}
public override var isEnabled: Bool {
didSet {
updateAccessibility()
}
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Lifecycle // MARK: - Lifecycle
//-------------------------------------------------- //--------------------------------------------------
@ -45,9 +57,9 @@ open class RadioSwatch: Control {
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData) super.set(with: model, delegateObject, additionalData)
guard let model = model as? RadioSwatchModel else { return } guard let model = model as? RadioSwatchModel else { return }
bottomText.text = model.text
isSelected = model.selected isSelected = model.selected
isEnabled = model.enabled isEnabled = model.enabled
bottomText.text = model.text
} }
public override func reset() { public override func reset() {
@ -163,4 +175,17 @@ open class RadioSwatch: Control {
mask.frame = bounds mask.frame = bounds
return mask return mask
} }
// MARK: - Accessibility
public func updateAccessibility() {
accessibilityLabel = bottomText.accessibilityLabel ?? bottomText.text
accessibilityTraits = .button
if isSelected {
accessibilityTraits.insert(.selected)
}
if !isEnabled {
accessibilityTraits.insert(.notEnabled)
}
}
} }

View File

@ -12,6 +12,7 @@ open class RadioSwatchCollectionViewCell: CollectionViewCell {
open override func setupView() { open override func setupView() {
super.setupView() super.setupView()
isAccessibilityElement = true
addMolecule(radioSwatch) addMolecule(radioSwatch)
MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0) MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0)
} }
@ -19,5 +20,24 @@ open class RadioSwatchCollectionViewCell: CollectionViewCell {
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let model = model as? RadioSwatchModel else { return } guard let model = model as? RadioSwatchModel else { return }
radioSwatch.set(with: model, delegateObject, additionalData) radioSwatch.set(with: model, delegateObject, additionalData)
updateAccessibility()
}
open func updateAccessibility() {
accessibilityLabel = radioSwatch.accessibilityLabel
accessibilityHint = radioSwatch.accessibilityHint
accessibilityTraits = radioSwatch.accessibilityTraits
}
open override func accessibilityElementDidBecomeFocused() {
super.accessibilityElementDidBecomeFocused()
radioSwatch.bottomText.isHidden = false
}
open override func accessibilityElementDidLoseFocus() {
super.accessibilityElementDidLoseFocus()
if !radioSwatch.isSelected {
radioSwatch.bottomText.isHidden = true
}
} }
} }

View File

@ -101,6 +101,13 @@ open class RadioSwatches: View {
} }
collectionViewHeight?.constant = CGFloat(height) collectionViewHeight?.constant = CGFloat(height)
} }
open func updateAccessibilityValue(collectionView: UICollectionView, cell: RadioSwatchCollectionViewCell, indexPath: IndexPath) {
guard let format = MVMCoreUIUtility.hardcodedString(withKey: "index_string_of_total"),
let indexString = MVMCoreUIUtility.getOrdinalString(forIndex: NSNumber(value: indexPath.row + 1)) else { return }
let total = self.collectionView(collectionView, numberOfItemsInSection: indexPath.section)
cell.accessibilityValue = String(format: format, indexString, total)
}
} }
//------------------------------------------------------ //------------------------------------------------------
@ -128,6 +135,7 @@ extension RadioSwatches: UICollectionViewDataSource {
if molecule.selected { if molecule.selected {
collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically) collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically)
} }
updateAccessibilityValue(collectionView: collectionView, cell: cell, indexPath: indexPath)
cell.layoutIfNeeded() cell.layoutIfNeeded()
return cell return cell
} }
@ -143,10 +151,12 @@ extension RadioSwatches: UICollectionViewDelegate {
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchCollectionViewCell else { return } guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchCollectionViewCell else { return }
cell.radioSwatch.selectSwatch() cell.radioSwatch.selectSwatch()
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
cell.updateAccessibility()
} }
open func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { open func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchCollectionViewCell else { return } guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchCollectionViewCell else { return }
cell.radioSwatch.deselectSwatch() cell.radioSwatch.deselectSwatch()
cell.updateAccessibility()
} }
} }

View File

@ -110,13 +110,10 @@ open class BarsIndicatorView: CarouselIndicator {
var bars = [(View, NSLayoutConstraint)]() var bars = [(View, NSLayoutConstraint)]()
let ordinalFormatter = NumberFormatter()
ordinalFormatter.numberStyle = .ordinal
for i in 0..<numberOfPages { for i in 0..<numberOfPages {
let bar = View() let bar = View()
bar.isAccessibilityElement = true bar.isAccessibilityElement = true
if let accessibleValueFormat = accessibilityValueFormat, let accessibleIndex = ordinalFormatter.string(from: NSNumber(value: i + 1)) { if let accessibleValueFormat = accessibilityValueFormat, let accessibleIndex = MVMCoreUIUtility.getOrdinalString(forIndex: NSNumber(value: i + 1)) {
bar.accessibilityLabel = String(format: accessibleValueFormat, accessibleIndex, numberOfPages) bar.accessibilityLabel = String(format: accessibleValueFormat, accessibleIndex, numberOfPages)
} }
bar.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccTabHint") bar.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccTabHint")

View File

@ -225,11 +225,8 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol {
func formatAccessibilityValue(index: Int, total: Int) { func formatAccessibilityValue(index: Int, total: Int) {
let ordinalFormatter = NumberFormatter()
ordinalFormatter.numberStyle = .ordinal
guard let accessibleFormat = accessibilityValueFormat, guard let accessibleFormat = accessibilityValueFormat,
let accessibleIndex = ordinalFormatter.string(from: NSNumber(value: index)) let accessibleIndex = MVMCoreUIUtility.getOrdinalString(forIndex: NSNumber(value: index))
else { return } else { return }
accessibilityValue = String(format: accessibleFormat, accessibleIndex, total) accessibilityValue = String(format: accessibleFormat, accessibleIndex, total)

View File

@ -0,0 +1,213 @@
//
// LoadingSpinner.swift
// MVMCoreUI
//
// Created by Kevin Christiano on 5/20/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import UIKit
open class LoadingSpinner: View {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public var strokeColor: UIColor = .mvmBlack
public var lineWidth: CGFloat = 4.0
public var speed: Float = 1.5
//--------------------------------------------------
// MARK: - Constraints
//--------------------------------------------------
public var heightConstraint: NSLayoutConstraint?
public var widthConstraint: NSLayoutConstraint?
//--------------------------------------------------
// MARK: - Lifecycle
//--------------------------------------------------
override open var layer: CAShapeLayer {
get { return super.layer as! CAShapeLayer }
}
override open class var layerClass: AnyClass {
return CAShapeLayer.self
}
open override func setupView() {
super.setupView()
heightConstraint = heightAnchor.constraint(equalToConstant: 0)
widthConstraint = widthAnchor.constraint(equalToConstant: 0)
}
override open func layoutSubviews() {
super.layoutSubviews()
layer.fillColor = nil
layer.strokeColor = strokeColor.cgColor
layer.lineWidth = lineWidth
layer.lineCap = .butt
layer.speed = speed
let halfWidth = lineWidth / 2
let radius = (bounds.width - lineWidth) / 2
layer.path = UIBezierPath(arcCenter: CGPoint(x: radius + halfWidth,
y: radius + halfWidth),
radius: radius,
startAngle: -CGFloat.pi / 2,
endAngle: 2 * CGFloat.pi,
clockwise: true).cgPath
}
open override func updateView(_ size: CGFloat) {
super.updateView(size)
layer.removeAllAnimations()
animate()
}
public override func reset() {
super.reset()
layer.removeAllAnimations()
heightConstraint?.isActive = false
widthConstraint?.isActive = false
}
//--------------------------------------------------
// MARK: - Animation
//--------------------------------------------------
override open func didMoveToWindow() {
animate()
}
struct Pose {
/// Delayed time (in seconds) to execute after the previous Pose.
let delay: CFTimeInterval
/// The time into the animation to begin drawing.
let startTime: CGFloat
/// The length of the drawn line.
let length: CGFloat
}
// TODO: This needs more attention to improve frame smoothness.
class var poses: [Pose] {
get {
return [
Pose(delay: 0.0, startTime: 0.000, length: 0.7),
Pose(delay: 0.7, startTime: 0.500, length: 0.5),
Pose(delay: 0.6, startTime: 1.000, length: 0.3),
Pose(delay: 0.5, startTime: 1.500, length: 0.2),
Pose(delay: 0.5, startTime: 1.875, length: 0.2),
Pose(delay: 0.3, startTime: 2.250, length: 0.3),
Pose(delay: 0.2, startTime: 2.600, length: 0.5),
Pose(delay: 0.2, startTime: 3.000, length: 0.7)
]
}
}
private func animate() {
var time: CFTimeInterval = 0
var times = [CFTimeInterval]()
var start: CGFloat = 0
var rotations = [CGFloat]()
var strokeEnds = [CGFloat]()
let poses = Self.poses
var totalSeconds: CFTimeInterval = poses.reduce(0) { $0 + $1.delay }
for pose in poses {
time += pose.delay
times.append(time / totalSeconds)
start = pose.startTime
rotations.append(start * 2 * CGFloat.pi)
strokeEnds.append(pose.length)
}
totalSeconds += 0.3
animateKeyPath(keyPath: "strokeEnd", duration: totalSeconds, times: times, values: strokeEnds)
animateKeyPath(keyPath: "transform.rotation", duration: totalSeconds, times: times, values: rotations)
}
private func animateKeyPath(keyPath: String, duration: CFTimeInterval, times: [CFTimeInterval], values: [CGFloat]) {
let animation = CAKeyframeAnimation(keyPath: keyPath)
animation.keyTimes = times as [NSNumber]?
animation.values = values
animation.calculationMode = .linear
animation.timingFunction = CAMediaTimingFunction(name: .linear)
animation.duration = duration
animation.rotationMode = .rotateAuto
animation.fillMode = .forwards
animation.isRemovedOnCompletion = false
animation.repeatCount = .infinity
layer.add(animation, forKey: animation.keyPath)
}
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
func resumeSpinnerAfterDelay() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
self?.resumeAnimations()
}
}
func pauseAnimations() {
let pausedTime = layer.convertTime(CACurrentMediaTime(), from: nil)
layer.speed = 0
isHidden = true
layer.timeOffset = pausedTime
}
func resumeAnimations() {
let pausedTime = layer.timeOffset
isHidden = false
layer.speed = speed
layer.timeOffset = 0
let timeSincePause = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
layer.beginTime = timeSincePause
}
func stopAllAnimations() {
layer.removeAllAnimations()
}
func pinWidthAndHeight(diameter: CGFloat) {
let dimension = diameter + lineWidth
heightConstraint?.constant = dimension
widthConstraint?.constant = dimension
heightConstraint?.isActive = true
widthConstraint?.isActive = true
}
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
//--------------------------------------------------
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? LoadingSpinnerModel else { return }
strokeColor = model.strokeColor.uiColor
lineWidth = model.lineWidth
pinWidthAndHeight(diameter: model.diameter)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 40.0
}
}

View File

@ -0,0 +1,65 @@
//
// LoadingSpinnerModel.swift
// MVMCoreUI
//
// Created by Kevin Christiano on 5/20/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
open class LoadingSpinnerModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public var backgroundColor: Color?
public static var identifier: String = "loadingSpinner"
public var strokeColor = Color(uiColor: .mvmBlack)
public var lineWidth: CGFloat = 4
public var diameter: CGFloat = 40
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case backgroundColor
case strokeColor
case lineWidth
case diameter
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
if let diameter = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .diameter) {
self.diameter = diameter
}
if let strokeColor = try typeContainer.decodeIfPresent(Color.self, forKey: .strokeColor) {
self.strokeColor = strokeColor
}
if let lineWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .lineWidth) {
self.lineWidth = lineWidth
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(diameter, forKey: .diameter)
try container.encode(strokeColor, forKey: .strokeColor)
try container.encode(lineWidth, forKey: .lineWidth)
}
}

View File

@ -392,8 +392,23 @@ public typealias ActionBlockConfirmation = () -> (Bool)
accessibilityLabel = accessibileString accessibilityLabel = accessibileString
} }
if let actionMap = model.action?.toJSON() { let actionMap = model.action?.toJSON()
didToggleAction = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) } let alternateActionMap = model.alternateAction?.toJSON()
if actionMap != nil || alternateActionMap != nil {
didToggleAction = { [weak self] in
guard let self = self else { return }
if self.isOn {
if actionMap != nil {
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
}
} else {
if alternateActionMap != nil {
MVMCoreActionHandler.shared()?.handleAction(with: alternateActionMap, additionalData: additionalData, delegateObject: delegateObject)
} else if actionMap != nil {
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
}
}
}
} }
} }

View File

@ -48,12 +48,12 @@ import Foundation
/// Call to register all of the CoreUI molecules. /// Call to register all of the CoreUI molecules.
public static func registerObjects() { public static func registerObjects() {
// Stacks // MARK:- Stacks
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeStackView.self, viewModelClass: StackModel.self) MoleculeObjectMapping.shared()?.register(viewClass: MoleculeStackView.self, viewModelClass: StackModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: UnOrderedList.self, viewModelClass: UnOrderedListModel.self) MoleculeObjectMapping.shared()?.register(viewClass: UnOrderedList.self, viewModelClass: UnOrderedListModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: NumberedList.self, viewModelClass: NumberedListModel.self) MoleculeObjectMapping.shared()?.register(viewClass: NumberedList.self, viewModelClass: NumberedListModel.self)
// Label // MARK:- Label
MoleculeObjectMapping.shared()?.register(viewClass: Label.self, viewModelClass: LabelModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Label.self, viewModelClass: LabelModel.self)
// need to move labelattributemodel to different method // need to move labelattributemodel to different method
try? ModelRegistry.register(LabelAttributeFontModel.self) try? ModelRegistry.register(LabelAttributeFontModel.self)
@ -63,24 +63,24 @@ import Foundation
try? ModelRegistry.register(LabelAttributeStrikeThroughModel.self) try? ModelRegistry.register(LabelAttributeStrikeThroughModel.self)
try? ModelRegistry.register(LabelAttributeActionModel.self) try? ModelRegistry.register(LabelAttributeActionModel.self)
// TextView // MARK:- TextView
MoleculeObjectMapping.shared()?.register(viewClass: TextViewEntryField.self, viewModelClass: TextViewEntryFieldModel.self) MoleculeObjectMapping.shared()?.register(viewClass: TextViewEntryField.self, viewModelClass: TextViewEntryFieldModel.self)
// Buttons // MARK:- Buttons
MoleculeObjectMapping.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self) MoleculeObjectMapping.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: TwoButtonView.self, viewModelClass: TwoButtonViewModel.self) MoleculeObjectMapping.shared()?.register(viewClass: TwoButtonView.self, viewModelClass: TwoButtonViewModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ExternalLink.self, viewModelClass: ExternalLinkModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ExternalLink.self, viewModelClass: ExternalLinkModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Link.self, viewModelClass: LinkModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Link.self, viewModelClass: LinkModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: CaretLink.self, viewModelClass: CaretLinkModel.self) MoleculeObjectMapping.shared()?.register(viewClass: CaretLink.self, viewModelClass: CaretLinkModel.self)
// Entry Field // MARK:- Entry Field
MoleculeObjectMapping.shared()?.register(viewClass: TextEntryField.self, viewModelClass: TextEntryFieldModel.self) MoleculeObjectMapping.shared()?.register(viewClass: TextEntryField.self, viewModelClass: TextEntryFieldModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MdnEntryField.self, viewModelClass: MdnEntryFieldModel.self) MoleculeObjectMapping.shared()?.register(viewClass: MdnEntryField.self, viewModelClass: MdnEntryFieldModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: DigitEntryField.self, viewModelClass: DigitEntryFieldModel.self) MoleculeObjectMapping.shared()?.register(viewClass: DigitEntryField.self, viewModelClass: DigitEntryFieldModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ItemDropdownEntryField.self, viewModelClass: ItemDropdownEntryFieldModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ItemDropdownEntryField.self, viewModelClass: ItemDropdownEntryFieldModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: DateDropdownEntryField.self, viewModelClass: DateDropdownEntryFieldModel.self) MoleculeObjectMapping.shared()?.register(viewClass: DateDropdownEntryField.self, viewModelClass: DateDropdownEntryFieldModel.self)
// Selectors // MARK:- Selectors
MoleculeObjectMapping.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self) MoleculeObjectMapping.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: RadioBoxes.self, viewModelClass: RadioBoxesModel.self) MoleculeObjectMapping.shared()?.register(viewClass: RadioBoxes.self, viewModelClass: RadioBoxesModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self)
@ -90,7 +90,7 @@ import Foundation
// Other Atoms // MARK:- Other Atoms
MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self) MoleculeObjectMapping.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: CaretView.self, viewModelClass: CaretViewModel.self) MoleculeObjectMapping.shared()?.register(viewClass: CaretView.self, viewModelClass: CaretViewModel.self)
@ -103,14 +103,15 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: Arrow.self, viewModelClass: ArrowModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Arrow.self, viewModelClass: ArrowModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: RadioButtonLabel.self, viewModelClass: RadioButtonLabelModel.self) MoleculeObjectMapping.shared()?.register(viewClass: RadioButtonLabel.self, viewModelClass: RadioButtonLabelModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: WebView.self, viewModelClass: WebViewModel.self) MoleculeObjectMapping.shared()?.register(viewClass: WebView.self, viewModelClass: WebViewModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: LoadingSpinner.self, viewModelClass: LoadingSpinnerModel.self)
// Horizontal Combination Molecules
// MARK:- Horizontal Combination Molecules
MoleculeObjectMapping.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self) MoleculeObjectMapping.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Tabs.self, viewModelClass: TabsModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Tabs.self, viewModelClass: TabsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: TwoLinkView.self, viewModelClass: TwoLinkViewModel.self) MoleculeObjectMapping.shared()?.register(viewClass: TwoLinkView.self, viewModelClass: TwoLinkViewModel.self)
// Vertical Combination Molecules // MARK:- Vertical Combination Molecules
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self) MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadLineBodyCaretLinkImage.self, viewModelClass: HeadlineBodyCaretLinkImageModel.self) MoleculeObjectMapping.shared()?.register(viewClass: HeadLineBodyCaretLinkImage.self, viewModelClass: HeadlineBodyCaretLinkImageModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: EyebrowHeadlineBodyLink.self, viewModelClass: EyebrowHeadlineBodyLinkModel.self) MoleculeObjectMapping.shared()?.register(viewClass: EyebrowHeadlineBodyLink.self, viewModelClass: EyebrowHeadlineBodyLinkModel.self)
@ -119,7 +120,7 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: BGImageHeadlineBodyButton.self, viewModelClass: BGImageHeadlineBodyButtonModel.self) MoleculeObjectMapping.shared()?.register(viewClass: BGImageHeadlineBodyButton.self, viewModelClass: BGImageHeadlineBodyButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ThreeHeadlineBodyLink.self, viewModelClass: ThreeHeadlineBodyLinkModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ThreeHeadlineBodyLink.self, viewModelClass: ThreeHeadlineBodyLinkModel.self)
// Left Right Molecules // MARK:- Left Right Molecules
MoleculeObjectMapping.shared()?.register(viewClass: CornerLabels.self, viewModelClass: CornerLabelsModel.self) MoleculeObjectMapping.shared()?.register(viewClass: CornerLabels.self, viewModelClass: CornerLabelsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: LeftRightLabelView.self, viewModelClass: LeftRightLabelModel.self) MoleculeObjectMapping.shared()?.register(viewClass: LeftRightLabelView.self, viewModelClass: LeftRightLabelModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: LabelToggle.self, viewModelClass: LabelToggleModel.self) MoleculeObjectMapping.shared()?.register(viewClass: LabelToggle.self, viewModelClass: LabelToggleModel.self)
@ -127,21 +128,21 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyLinkToggle.self, viewModelClass: HeadlineBodyLinkToggleModel.self) MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyLinkToggle.self, viewModelClass: HeadlineBodyLinkToggleModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ActionDetailWithImage.self, viewModelClass: ActionDetailWithImageModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ActionDetailWithImage.self, viewModelClass: ActionDetailWithImageModel.self)
// List items // MARK:- List items
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeTableViewCell.self, viewModelClass: MoleculeListItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: MoleculeTableViewCell.self, viewModelClass: MoleculeListItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: DropDownFilterTableViewCell.self, viewModelClass: DropDownListItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: DropDownFilterTableViewCell.self, viewModelClass: DropDownListItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: AccordionMoleculeTableViewCell.self, viewModelClass: AccordionListItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: AccordionMoleculeTableViewCell.self, viewModelClass: AccordionListItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: TabsTableViewCell.self, viewModelClass: TabsListItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: TabsTableViewCell.self, viewModelClass: TabsListItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListProgressBarData.self, viewModelClass: ListProgressBarDataModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListProgressBarData.self, viewModelClass: ListProgressBarDataModel.self)
// Other Items // MARK:- Other Items
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeStackItem.self, viewModelClass: MoleculeStackItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: MoleculeStackItem.self, viewModelClass: MoleculeStackItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: StackItem.self, viewModelClass: StackItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: StackItem.self, viewModelClass: StackItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeCollectionViewCell.self, viewModelClass: MoleculeCollectionItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: MoleculeCollectionViewCell.self, viewModelClass: MoleculeCollectionItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: CarouselItem.self, viewModelClass: CarouselItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: CarouselItem.self, viewModelClass: CarouselItemModel.self)
// Other Container Molecules // MARK:- Other Container Molecules
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeContainer.self, viewModelClass: MoleculeContainerModel.self) MoleculeObjectMapping.shared()?.register(viewClass: MoleculeContainer.self, viewModelClass: MoleculeContainerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeHeaderView.self, viewModelClass: MoleculeHeaderModel.self) MoleculeObjectMapping.shared()?.register(viewClass: MoleculeHeaderView.self, viewModelClass: MoleculeHeaderModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: FooterView.self, viewModelClass: FooterModel.self) MoleculeObjectMapping.shared()?.register(viewClass: FooterView.self, viewModelClass: FooterModel.self)
@ -149,7 +150,7 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: ModuleMolecule.self, viewModelClass: ModuleMoleculeModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ModuleMolecule.self, viewModelClass: ModuleMoleculeModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: BGImageMolecule.self, viewModelClass: BGImageMoleculeModel.self) MoleculeObjectMapping.shared()?.register(viewClass: BGImageMolecule.self, viewModelClass: BGImageMoleculeModel.self)
// Other Molecules // MARK:- Other Molecules
MoleculeObjectMapping.shared()?.register(viewClass: DoughnutChartView.self, viewModelClass: DoughnutChartModel.self) MoleculeObjectMapping.shared()?.register(viewClass: DoughnutChartView.self, viewModelClass: DoughnutChartModel.self)
// Navigation Molecules // Navigation Molecules
@ -157,12 +158,12 @@ import Foundation
try? ModelRegistry.register(NavigationImageButtonModel.self) try? ModelRegistry.register(NavigationImageButtonModel.self)
try? ModelRegistry.register(NavigationLabelButtonModel.self) try? ModelRegistry.register(NavigationLabelButtonModel.self)
// Other Organisms // MARK:- Other Organisms
MoleculeObjectMapping.shared()?.register(viewClass: Carousel.self, viewModelClass: CarouselModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Carousel.self, viewModelClass: CarouselModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: BarsIndicatorView.self, viewModelClass: BarsCarouselIndicatorModel.self) MoleculeObjectMapping.shared()?.register(viewClass: BarsIndicatorView.self, viewModelClass: BarsCarouselIndicatorModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: NumericIndicatorView.self, viewModelClass: NumericCarouselIndicatorModel.self) MoleculeObjectMapping.shared()?.register(viewClass: NumericIndicatorView.self, viewModelClass: NumericCarouselIndicatorModel.self)
// Designed List Items // MARK:- Designed List Items
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaret.self, viewModelClass: ListLeftVariableIconWithRightCaretModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaret.self, viewModelClass: ListLeftVariableIconWithRightCaretModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaretBodyText.self, viewModelClass: ListLeftVariableIconWithRightCaretBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaretBodyText.self, viewModelClass: ListLeftVariableIconWithRightCaretBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxAllTextAndLinks.self, viewModelClass: ListLeftVariableCheckboxAllTextAndLinksModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxAllTextAndLinks.self, viewModelClass: ListLeftVariableCheckboxAllTextAndLinksModel.self)
@ -192,7 +193,7 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListProgressBarThin.self, viewModelClass: ListProgressBarThinModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListProgressBarThin.self, viewModelClass: ListProgressBarThinModel.self)
// Designed Section Dividers // MARK:- Designed Section Dividers
MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnPlanDataDivider.self, viewModelClass: ListThreeColumnPlanDataDividerModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnPlanDataDivider.self, viewModelClass: ListThreeColumnPlanDataDividerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnTextWithWhitespaceDividerShort.self, viewModelClass: ListOneColumnTextWithWhitespaceDividerShortModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnTextWithWhitespaceDividerShort.self, viewModelClass: ListOneColumnTextWithWhitespaceDividerShortModel.self)
@ -204,7 +205,7 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnBillChangesDivider.self, viewModelClass: ListThreeColumnBillChangesDividerModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnBillChangesDivider.self, viewModelClass: ListThreeColumnBillChangesDividerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnDataUsageDivider.self, viewModelClass: ListThreeColumnDataUsageDividerModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnDataUsageDivider.self, viewModelClass: ListThreeColumnDataUsageDividerModel.self)
// Designed Headers // MARK:- Designed Headers
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH1Button.self, viewModelClass: HeadersH1ButtonModel.self) MoleculeObjectMapping.shared()?.register(viewClass: HeadersH1Button.self, viewModelClass: HeadersH1ButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH1LandingPageHeader.self, viewModelClass: HeadersH1LandingPageHeaderModel.self) MoleculeObjectMapping.shared()?.register(viewClass: HeadersH1LandingPageHeader.self, viewModelClass: HeadersH1LandingPageHeaderModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2NoButtonsBodyText.self, viewModelClass: HeadersH2NoButtonsBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2NoButtonsBodyText.self, viewModelClass: HeadersH2NoButtonsBodyTextModel.self)
@ -212,15 +213,16 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2Buttons.self, viewModelClass: HeadersH2ButtonsModel.self) MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2Buttons.self, viewModelClass: HeadersH2ButtonsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2PricingTwoRows.self, viewModelClass: HeadersH2PricingTwoRowsModel.self) MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2PricingTwoRows.self, viewModelClass: HeadersH2PricingTwoRowsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2Link.self, viewModelClass: HeadersH2LinkModel.self) MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2Link.self, viewModelClass: HeadersH2LinkModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2CaretLink.self, viewModelClass: HeadersH2CaretLinkModel.self)
// Device Items // MARK:- Device Items
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonMedium.self, viewModelClass: ListDeviceComplexButtonMediumModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonMedium.self, viewModelClass: ListDeviceComplexButtonMediumModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonSmall.self, viewModelClass: ListDeviceComplexButtonSmallModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonSmall.self, viewModelClass: ListDeviceComplexButtonSmallModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkSmall.self, viewModelClass: ListDeviceComplexLinkSmallModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkSmall.self, viewModelClass: ListDeviceComplexLinkSmallModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkMedium.self, viewModelClass: ListDeviceComplexLinkMediumModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkMedium.self, viewModelClass: ListDeviceComplexLinkMediumModel.self)
// Helper models // MARK:- Helper models
try? ModelRegistry.register(RuleRequiredModel.self) try? ModelRegistry.register(RuleRequiredModel.self)
try? ModelRegistry.register(RuleAnyRequiredModel.self) try? ModelRegistry.register(RuleAnyRequiredModel.self)
try? ModelRegistry.register(RuleAnyValueChangedModel.self) try? ModelRegistry.register(RuleAnyValueChangedModel.self)
@ -229,12 +231,12 @@ import Foundation
try? ModelRegistry.register(RuleEqualsIgnoreCaseModel.self) try? ModelRegistry.register(RuleEqualsIgnoreCaseModel.self)
try? ModelRegistry.register(RuleRegexModel.self) try? ModelRegistry.register(RuleRegexModel.self)
// Actions // MARK:- Actions
try? ModelRegistry.register(ActionTopAlertModel.self) try? ModelRegistry.register(ActionTopAlertModel.self)
try? ModelRegistry.register(ActionCollapseNotificationModel.self) try? ModelRegistry.register(ActionCollapseNotificationModel.self)
try? ModelRegistry.register(ActionOpenPanelModel.self) try? ModelRegistry.register(ActionOpenPanelModel.self)
// Behaviors // MARK:- Behaviors
try? ModelRegistry.register(ScreenBrightnessModifierBehavior.self) try? ModelRegistry.register(ScreenBrightnessModifierBehavior.self)
} }

View File

@ -0,0 +1,58 @@
//
// HeadersH2CaretLink.swift
// MVMCoreUI
//
// Created by Lekshmi S on 01/07/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class HeadersH2CaretLink: HeaderView {
//--------------------------------------------------
// MARK: - Outlets
//--------------------------------------------------
public let headlineBody = HeadlineBody()
public let caretLink = CaretLink()
public let stack: Stack<StackModel>
//-------------------------------------------------------
// MARK: - Initializers
//-------------------------------------------------------
public override init(frame: CGRect) {
stack = Stack<StackModel>.createStack(with: [headlineBody, caretLink])
super.init(frame: frame)
}
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//-------------------------------------------------------
// MARK: - 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? HeadersH2CaretLinkModel else { return }
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
caretLink.set(with: model.caretLink, delegateObject, additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 121
}
open override func reset() {
super.reset()
headlineBody.stylePageHeader()
}
}

View File

@ -0,0 +1,66 @@
//
// HeadersH2CaretLinkModel.swift
// MVMCoreUI
//
// Created by Lekshmi S on 01/07/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class HeadersH2CaretLinkModel: HeaderModel, MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "headerH2CrtBtn"
public var headlineBody: HeadlineBodyModel
public var caretLink: CaretLinkModel
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(headlineBody: HeadlineBodyModel, caretLink: CaretLinkModel) {
self.headlineBody = headlineBody
self.caretLink = caretLink
super.init()
}
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
super.setDefaults()
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case headlineBody
case caretLink
}
//--------------------------------------------------
// 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)
caretLink = try typeContainer.decode(CaretLinkModel.self, forKey: .caretLink)
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(caretLink, forKey: .caretLink)
}
}

View File

@ -33,10 +33,9 @@ public class ListTwoColumnPriceDetailsModel: ListItemModel, MoleculeModelProtoco
//-------------------------------------------------- //--------------------------------------------------
override public func setDefaults() { override public func setDefaults() {
style = ListItemStyle.none
super.setDefaults() super.setDefaults()
style = "none"
if leftLabel.textColor == nil { if leftLabel.textColor == nil {
leftLabel.textColor = Color(uiColor: .mvmCoolGray6) leftLabel.textColor = Color(uiColor: .mvmCoolGray6)
} }

View File

@ -33,8 +33,8 @@ public class ListFourColumnDataUsageDividerModel: ListItemModel, MoleculeModelPr
} }
override public func setDefaults() { override public func setDefaults() {
style = .tallDivider
super.setDefaults() super.setDefaults()
style = "tallDivider"
} }
//-------------------------------------------------- //--------------------------------------------------

View File

@ -33,8 +33,8 @@ public class ListOneColumnFullWidthTextDividerSubsectionModel: ListItemModel, Mo
//-------------------------------------------------- //--------------------------------------------------
override public func setDefaults() { override public func setDefaults() {
style = .tallDivider
super.setDefaults() super.setDefaults()
style = "tallDivider"
} }
//-------------------------------------------------- //--------------------------------------------------

View File

@ -33,8 +33,8 @@ public class ListOneColumnTextWithWhitespaceDividerShortModel: ListItemModel, Mo
//-------------------------------------------------- //--------------------------------------------------
override public func setDefaults() { override public func setDefaults() {
style = .shortDivider
super.setDefaults() super.setDefaults()
style = "shortDivider"
} }
//-------------------------------------------------- //--------------------------------------------------

View File

@ -33,8 +33,8 @@ public class ListOneColumnTextWithWhitespaceDividerTallModel: ListItemModel, Mol
//-------------------------------------------------- //--------------------------------------------------
override public func setDefaults() { override public func setDefaults() {
style = .tallDivider
super.setDefaults() super.setDefaults()
style = "tallDivider"
} }
//-------------------------------------------------- //--------------------------------------------------

View File

@ -35,8 +35,8 @@ public class ListThreeColumnBillChangesDividerModel: ListItemModel, MoleculeMode
//----------------------------------------------------- //-----------------------------------------------------
override public func setDefaults() { override public func setDefaults() {
style = .tallDivider
super.setDefaults() super.setDefaults()
style = "tallDivider"
} }
//----------------------------------------------------- //-----------------------------------------------------

View File

@ -35,8 +35,8 @@ public class ListThreeColumnDataUsageDividerModel: ListItemModel, MoleculeModelP
//----------------------------------------------------- //-----------------------------------------------------
override public func setDefaults() { override public func setDefaults() {
style = .tallDivider
super.setDefaults() super.setDefaults()
style = "tallDivider"
} }
//----------------------------------------------------- //-----------------------------------------------------

View File

@ -35,8 +35,8 @@ public class ListThreeColumnInternationalDataDividerModel: ListItemModel, Molecu
//------------------------------------------------------ //------------------------------------------------------
override public func setDefaults() { override public func setDefaults() {
style = .tallDivider
super.setDefaults() super.setDefaults()
style = "tallDivider"
} }
//------------------------------------------------------ //------------------------------------------------------

View File

@ -35,8 +35,8 @@ public class ListThreeColumnPlanDataDividerModel: ListItemModel, MoleculeModelPr
//----------------------------------------------------- //-----------------------------------------------------
override public func setDefaults() { override public func setDefaults() {
style = .tallDivider
super.setDefaults() super.setDefaults()
style = "tallDivider"
leftHeadlineBody.style = .itemHeader leftHeadlineBody.style = .itemHeader
centerHeadlineBody.style = .itemHeader centerHeadlineBody.style = .itemHeader
rightHeadlineBody.style = .itemHeader rightHeadlineBody.style = .itemHeader

View File

@ -35,8 +35,8 @@ public class ListThreeColumnSpeedTestDividerModel: ListItemModel, MoleculeModelP
//----------------------------------------------------- //-----------------------------------------------------
override public func setDefaults() { override public func setDefaults() {
style = .tallDivider
super.setDefaults() super.setDefaults()
style = "tallDivider"
} }
//----------------------------------------------------- //-----------------------------------------------------

View File

@ -33,8 +33,8 @@ public class ListTwoColumnSubsectionDividerModel: ListItemModel, MoleculeModelPr
//------------------------------------------------------ //------------------------------------------------------
override public func setDefaults() { override public func setDefaults() {
style = .tallDivider
super.setDefaults() super.setDefaults()
style = "tallDivider"
} }
//------------------------------------------------------ //------------------------------------------------------

View File

@ -24,10 +24,10 @@ import Foundation
/// Defaults to set /// Defaults to set
public override func setDefaults() { public override func setDefaults() {
style = .sectionFooter
super.setDefaults() super.setDefaults()
hideArrow = true hideArrow = true
line = LineModel(type: .none) line = LineModel(type: .none)
style = "sectionFooter"
} }
//-------------------------------------------------- //--------------------------------------------------

View File

@ -11,6 +11,7 @@ import Foundation
@objcMembers open class ListItemModel: ContainerModel, ListItemModelProtocol { @objcMembers open class ListItemModel: ContainerModel, ListItemModelProtocol {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
@ -19,7 +20,7 @@ import Foundation
public var action: ActionModelProtocol? public var action: ActionModelProtocol?
public var hideArrow: Bool? public var hideArrow: Bool?
public var line: LineModel? public var line: LineModel?
public var style: String? public var style: ListItemStyle? = .standard
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Keys // MARK: - Keys
@ -39,17 +40,39 @@ import Foundation
/// Defaults to set /// Defaults to set
open override func setDefaults() { open override func setDefaults() {
if useHorizontalMargins == nil { setByStyle()
useHorizontalMargins = true }
/// Convenience function to set common values.
open func set(useHorizontalMargins: Bool? = true, useVerticalMargins: Bool? = true, topPadding: CGFloat? = nil, bottomPadding: CGFloat? = nil) {
if self.useHorizontalMargins == nil {
self.useHorizontalMargins = useHorizontalMargins
} }
if useVerticalMargins == nil { if self.useVerticalMargins == nil {
useVerticalMargins = true self.useVerticalMargins = useVerticalMargins
} }
if topPadding == nil { if self.topPadding == nil {
topPadding = 24 self.topPadding = topPadding
} }
if bottomPadding == nil { if self.bottomPadding == nil {
bottomPadding = 24 self.bottomPadding = bottomPadding
}
}
/// Convenience function to set common values based on style.
open func setByStyle() {
guard let style = style else { return }
switch style {
case .standard:
set(topPadding: Padding.Component.VerticalMarginSpacing, bottomPadding: Padding.Component.VerticalMarginSpacing)
case .shortDivider:
set(topPadding: Padding.Component.LargeVerticalMarginSpacing, bottomPadding: Padding.Four)
case .tallDivider:
set(topPadding: Padding.Twelve, bottomPadding: Padding.Four)
case .sectionFooter:
set(topPadding: Padding.Component.VerticalMarginSpacing, bottomPadding: 0)
case ListItemStyle.none:
set(topPadding: 0, bottomPadding: 0)
} }
} }
@ -57,6 +80,12 @@ import Foundation
// MARK: - Initializer // MARK: - Initializer
//-------------------------------------------------- //--------------------------------------------------
public init(style: ListItemStyle? = .standard, action: ActionModelProtocol?) {
self.style = style
self.action = action
super.init()
}
public override init(horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil, useHorizontalMargins: Bool? = nil, leftPadding: CGFloat? = nil, rightPadding: CGFloat? = nil, useVerticalMargins: Bool? = nil, topPadding: CGFloat? = nil, bottomPadding: CGFloat? = nil) { public override init(horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil, useHorizontalMargins: Bool? = nil, leftPadding: CGFloat? = nil, rightPadding: CGFloat? = nil, useVerticalMargins: Bool? = nil, topPadding: CGFloat? = nil, bottomPadding: CGFloat? = nil) {
super.init(horizontalAlignment: horizontalAlignment, verticalAlignment: verticalAlignment, useHorizontalMargins: useHorizontalMargins, leftPadding: leftPadding, rightPadding: rightPadding, useVerticalMargins: useVerticalMargins, topPadding: topPadding, bottomPadding: bottomPadding) super.init(horizontalAlignment: horizontalAlignment, verticalAlignment: verticalAlignment, useHorizontalMargins: useHorizontalMargins, leftPadding: leftPadding, rightPadding: rightPadding, useVerticalMargins: useVerticalMargins, topPadding: topPadding, bottomPadding: bottomPadding)
} }
@ -75,7 +104,9 @@ import Foundation
action = try typeContainer.decodeModelIfPresent(codingKey: .action) action = try typeContainer.decodeModelIfPresent(codingKey: .action)
hideArrow = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideArrow) hideArrow = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideArrow)
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
style = try typeContainer.decodeIfPresent(String.self, forKey: .style) if let style = try typeContainer.decodeIfPresent(ListItemStyle.self, forKey: .style) {
self.style = style
}
try super.init(from: decoder) try super.init(from: decoder)
} }

View File

@ -8,12 +8,19 @@
import Foundation import Foundation
public enum ListItemStyle: String, Codable {
case standard
case shortDivider
case tallDivider
case sectionFooter
case none
}
public protocol ListItemModelProtocol: ContainerModelProtocol { public protocol ListItemModelProtocol: ContainerModelProtocol {
var line: LineModel? { get set } var line: LineModel? { get set }
var action: ActionModelProtocol? { get set } var action: ActionModelProtocol? { get set }
var hideArrow: Bool? { get set } var hideArrow: Bool? { get set }
var style: String? { get set } var style: ListItemStyle? { get set }
} }
// Not a strict requirement. // Not a strict requirement.
@ -24,7 +31,7 @@ public extension ListItemModelProtocol {
set { } set { }
} }
var style: String? { var style: ListItemStyle? {
get { return nil } get { return nil }
set { } set { }
} }

View File

@ -9,6 +9,9 @@
import Foundation import Foundation
@objc public protocol TabBarProtocol { @objc public protocol TabBarProtocol {
var delegateObject: MVMCoreUIDelegateObject? { get set }
/// Should visually select the given tab index. /// Should visually select the given tab index.
@objc func highlightTab(at index: Int) @objc func highlightTab(at index: Int)

View File

@ -11,16 +11,23 @@ import Foundation
public protocol TemplateProtocol: AnyObject { public protocol TemplateProtocol: AnyObject {
associatedtype TemplateModel: TemplateModelProtocol associatedtype TemplateModel: TemplateModelProtocol
var templateModel: TemplateModel? { get set } var templateModel: TemplateModel? { get set }
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel
} }
public extension TemplateProtocol where Self: ViewController { public extension TemplateProtocol where Self: ViewController {
func parseTemplate(json: [AnyHashable: Any]?) throws { func parseTemplate(json: [AnyHashable: Any]?) throws {
guard let pageJSON = json else { return } guard let pageJSON = json else { return }
let data = try JSONSerialization.data(withJSONObject: pageJSON) let data = try JSONSerialization.data(withJSONObject: pageJSON)
let decoder = JSONDecoder() let decoder = JSONDecoder()
try decoder.add(delegateObject: delegateObjectIVar) try decoder.add(delegateObject: delegateObjectIVar)
let templateModel = try decoder.decode(TemplateModel.self, from: data) self.templateModel = try decodeTemplate(using: decoder, from: data)
self.templateModel = templateModel
self.pageModel = templateModel as? MVMControllerModelProtocol self.pageModel = templateModel as? MVMControllerModelProtocol
} }
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel {
return try decoder.decode(TemplateModel.self, from: data)
}
} }

View File

@ -8,12 +8,12 @@
import Foundation import Foundation
@objcMembers public class ListPageTemplateModel: ThreeLayerModelBase { @objcMembers open class ListPageTemplateModel: ThreeLayerModelBase {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
public override class var identifier: String { open override class var identifier: String {
return "list" return "list"
} }
public var molecules: [ListItemModelProtocol & MoleculeModelProtocol]? public var molecules: [ListItemModelProtocol & MoleculeModelProtocol]?
@ -49,7 +49,7 @@ import Foundation
try super.init(from: decoder) try super.init(from: decoder)
} }
public override func encode(to encoder: Encoder) throws { open override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder) try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self) var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeModelsIfPresent(molecules, forKey: .molecules) try container.encodeModelsIfPresent(molecules, forKey: .molecules)

View File

@ -28,6 +28,11 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
try super.parsePageJSON() try super.parsePageJSON()
} }
// For subclassing the model.
open func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> ListPageTemplateModel {
return try decoder.decode(ListPageTemplateModel.self, from: data)
}
open override var loadObject: MVMCoreLoadObject? { open override var loadObject: MVMCoreLoadObject? {
didSet { didSet {
guard loadObject != oldValue else { return } guard loadObject != oldValue else { return }

View File

@ -9,7 +9,8 @@
import Foundation import Foundation
@objcMembers public class TemplateModel: MVMControllerModelProtocol, TabPageModelProtocol { @objcMembers open class TemplateModel: MVMControllerModelProtocol, TabPageModelProtocol {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------

View File

@ -8,7 +8,7 @@
import Foundation import Foundation
@objcMembers public class ThreeLayerModelBase: TemplateModel, ThreeLayerTemplateModelProtocol { @objcMembers open class ThreeLayerModelBase: TemplateModel, ThreeLayerTemplateModelProtocol {
public var anchorHeader: Bool = false public var anchorHeader: Bool = false
public var header: MoleculeModelProtocol? public var header: MoleculeModelProtocol?
public var anchorFooter: Bool = false public var anchorFooter: Bool = false

View File

@ -31,60 +31,33 @@ import UIKit
private var initialSetupPerformed = false private var initialSetupPerformed = false
// MARK: - Styling // MARK: - Styling
open func style(with styleString: String?) { open func styleLine(with style: ListItemStyle?) {
guard let styleString = styleString else { switch style {
return case .standard?:
} topSeparatorView?.setStyle(.none)
switch styleString { bottomSeparatorView?.setStyle(.standard)
case "standard": case .shortDivider?:
styleStandard() topSeparatorView?.setStyle(.none)
case "shortDivider": bottomSeparatorView?.setStyle(.thin)
styleShortDivider() case .tallDivider?:
case "tallDivider": topSeparatorView?.setStyle(.none)
styleTallDivider() bottomSeparatorView?.setStyle(.thin)
case "sectionFooter": case .sectionFooter?:
styleFooter() topSeparatorView?.setStyle(.none)
case "none": bottomSeparatorView?.setStyle(.none)
styleNone() case ListItemStyle.none?:
topSeparatorView?.setStyle(.none)
bottomSeparatorView?.setStyle(.none)
default: break default: break
} }
} }
/// Default state.
open func styleStandard() { open func styleStandard() {
listItemModel?.topPadding = 24 MFStyler.setMarginsFor(self, size: MVMCoreUIUtility.getWidth(), defaultHorizontal: true, top: Padding.Component.VerticalMarginSpacing, bottom: Padding.Component.VerticalMarginSpacing)
listItemModel?.bottomPadding = 24 styleLine(with: .standard)
topSeparatorView?.setStyle(.none)
bottomSeparatorView?.setStyle(.standard)
} }
open func styleTallDivider() {
listItemModel?.topPadding = 48
listItemModel?.bottomPadding = 16
topSeparatorView?.setStyle(.none)
bottomSeparatorView?.setStyle(.thin)
}
open func styleShortDivider() {
listItemModel?.topPadding = 32
listItemModel?.bottomPadding = 16
topSeparatorView?.setStyle(.none)
bottomSeparatorView?.setStyle(.thin)
}
open func styleFooter() {
listItemModel?.topPadding = 24
listItemModel?.bottomPadding = 0
topSeparatorView?.setStyle(.none)
bottomSeparatorView?.setStyle(.none)
}
open func styleNone() {
listItemModel?.topPadding = 0
listItemModel?.bottomPadding = 0
topSeparatorView?.setStyle(.none)
bottomSeparatorView?.setStyle(.none)
}
/// Adds the molecule to the view. /// Adds the molecule to the view.
open func addMolecule(_ molecule: MoleculeViewProtocol) { open func addMolecule(_ molecule: MoleculeViewProtocol) {
contentView.addSubview(molecule) contentView.addSubview(molecule)
@ -156,7 +129,7 @@ import UIKit
guard let model = model as? ListItemModelProtocol else { return } guard let model = model as? ListItemModelProtocol else { return }
self.listItemModel = model self.listItemModel = model
style(with: model.style) styleLine(with: model.style)
// Add the caret if there is an action and it's not declared hidden. // Add the caret if there is an action and it's not declared hidden.
if !customAccessoryView { if !customAccessoryView {

View File

@ -94,9 +94,10 @@ import UIKit
try parsePageJSON() try parsePageJSON()
MVMCoreDispatchUtility.performBlock(onMainThread: { MVMCoreDispatchUtility.performBlock(onMainThread: {
self.handleNewDataAndUpdateUI() self.handleNewDataAndUpdateUI()
// If the screen is showing, can update the navigation controller.
if MVMCoreUIUtility.getCurrentVisibleController() == self.manager ?? self { // Update navigation bar if showing.
self.setNavigationController() if MVMCoreUIUtility.getCurrentVisibleController() == self {
self.setNavigationBar()
} }
}) })
} catch { } catch {
@ -157,7 +158,7 @@ import UIKit
open func parsePageJSON() throws { open func parsePageJSON() throws {
} }
open class func verifyRequiredModulesLoaded(for loadObject: MVMCoreLoadObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool { open class func verifyRequiredModulesLoaded(for loadObject: MVMCoreLoadObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
guard let pageType = loadObject?.pageType, var modulesRequired = MVMCoreUIViewControllerMappingObject.shared()?.modulesRequired(forPageType: pageType), guard let pageType = loadObject?.pageType, var modulesRequired = MVMCoreUIViewControllerMappingObject.shared()?.modulesRequired(forPageType: pageType),
!modulesRequired.isEmpty else { return true } !modulesRequired.isEmpty else { return true }
@ -196,12 +197,6 @@ import UIKit
/// Processes any new data. Called after the page is loaded the first time and on response updates for this page, /// Processes any new data. Called after the page is loaded the first time and on response updates for this page,
open func handleNewData() { open func handleNewData() {
// TODO: remove legacy. Temporary, convert legacy to navigation model.
if pageModel?.navigationBar == nil {
let navigationItem = createDefaultLegacyNavigationModel()
pageModel?.navigationBar = navigationItem
}
if formValidator == nil { if formValidator == nil {
let rules = pageModel?.formRules let rules = pageModel?.formRules
formValidator = FormValidator(rules) formValidator = FormValidator(rules)
@ -210,20 +205,43 @@ import UIKit
if let backgroundColor = pageModel?.backgroundColor { if let backgroundColor = pageModel?.backgroundColor {
view.backgroundColor = backgroundColor.uiColor view.backgroundColor = backgroundColor.uiColor
} }
// Sets up the navigation item based on the data.
setNavigationItem()
} }
// MARK: - Navigation Item (Move to model base) // MARK: - Navigation Item (Move to model base)
open func setNavigationController() {
open func getNavigationModel() -> NavigationItemModelProtocol? {
// TODO: remove legacy. Temporary, convert legacy to navigation model.
if pageModel?.navigationBar == nil {
let navigationItem = createDefaultLegacyNavigationModel()
pageModel?.navigationBar = navigationItem
}
return pageModel?.navigationBar
}
/// Sets the navigation item for this view controller.
open func setNavigationItem() {
guard let navigationItemModel = getNavigationModel(),
let navigationController = navigationController else { return }
// We additionally want our left items
navigationItem.leftItemsSupplementBackButton = true
// Utilize helper function to set the navigation item state.
NavigationController.setNavigationItem(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: self)
}
/// Sets the appearance of the navigation bar based on the model.
open func setNavigationBar() {
let viewController = manager ?? self let viewController = manager ?? self
guard let navigationItemModel = pageModel?.navigationBar, guard let navigationItemModel = getNavigationModel(),
let navigationController = viewController.navigationController else { let navigationController = viewController.navigationController else {
MVMCoreUISession.sharedGlobal()?.splitViewController?.parent?.setNeedsStatusBarAppearanceUpdate() MVMCoreUISession.sharedGlobal()?.splitViewController?.parent?.setNeedsStatusBarAppearanceUpdate()
return return
} }
// We additionally want our left items
navigationItem.leftItemsSupplementBackButton = true
// Utilize helper function to set the split view and navigation item state. // Utilize helper function to set the split view and navigation item state.
MVMCoreUISplitViewController.setSplitViewController(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel, leftPanelAccessible: isMasterInitiallyAccessible(), rightPanelAccessible: isSupportInitiallyAccessible(), progress: bottomProgress() ?? 0) MVMCoreUISplitViewController.setSplitViewController(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel, leftPanelAccessible: isMasterInitiallyAccessible(), rightPanelAccessible: isSupportInitiallyAccessible(), progress: bottomProgress() ?? 0)
} }
@ -277,6 +295,7 @@ import UIKit
open func updateTabBar() { open func updateTabBar() {
guard MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() == self, guard MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() == self,
let tabModel = pageModel as? TabPageModelProtocol else { return } let tabModel = pageModel as? TabPageModelProtocol else { return }
MVMCoreUISplitViewController.main()?.tabBar?.delegateObject = delegateObjectIVar
if let index = tabModel.tabBarIndex { if let index = tabModel.tabBarIndex {
MVMCoreUISplitViewController.main()?.tabBar?.highlightTab(at: index) MVMCoreUISplitViewController.main()?.tabBar?.highlightTab(at: index)
} }
@ -336,7 +355,7 @@ import UIKit
open func pageShown() { open func pageShown() {
// Update the navigation bar ui when view is appearing. // Update the navigation bar ui when view is appearing.
setNavigationController() setNavigationBar()
// Update tab if needed. // Update tab if needed.
updateTabBar() updateTabBar()
@ -453,7 +472,7 @@ import UIKit
// Reset the navigation state. // Reset the navigation state.
public func splitViewDidReset() { public func splitViewDidReset() {
setNavigationController() setNavigationBar()
} }
// MARK: - UITextFieldDelegate (Check if this is still needed) // MARK: - UITextFieldDelegate (Check if this is still needed)

View File

@ -71,149 +71,153 @@ extension UIColor {
//-------------------------------------------------- //--------------------------------------------------
/// HEX: #D52B1E /// HEX: #D52B1E
public static let mvmRed = UIColor.color8Bits(red: 213, green: 43, blue: 30) public static let mvmRed = UIColor.assetColor(named: "red")
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Pink // MARK: - Pink
//-------------------------------------------------- //--------------------------------------------------
/// HEX: #D90368 /// HEX: #D90368
public static let mvmPink = UIColor.color8Bits(red: 217, green: 3, blue: 104) public static let mvmPink = UIColor.assetColor(named: "pink")
/// HEX: #F2ABCD /// HEX: #F2ABCD
public static let mvmPink33 = UIColor.color8Bits(red: 242, green: 171, blue: 205) public static let mvmPink33 = UIColor.assetColor(named: "pink33")
/// HEX: #E6589B /// HEX: #E6589B
public static let mvmPink66 = UIColor.color8Bits(red: 230, green: 88, blue: 155) public static let mvmPink66 = UIColor.assetColor(named: "pink66")
/// HEX: #B31C63 /// HEX: #B31C63
public static let mvmPinkShade1 = UIColor.color8Bits(red: 179, green: 28, blue: 99) public static let mvmPinkShade1 = UIColor.assetColor(named: "pinkShade1")
/// HEX: #830842 /// HEX: #830842
public static let mvmPinkShade2 = UIColor.color8Bits(red: 131, green: 8, blue: 66) public static let mvmPinkShade2 = UIColor.assetColor(named: "pinkShade2")
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Purple // MARK: - Purple
//-------------------------------------------------- //--------------------------------------------------
/// HEX: #8C00AC /// HEX: #8C00AC
public static let mvmPurple = UIColor.color8Bits(red: 140, green: 0, blue: 172) public static let mvmPurple = UIColor.assetColor(named: "purple")
/// HEX: #D9ABE4 /// HEX: #D9ABE4
public static let mvmPurple33 = UIColor.color8Bits(red: 217, green: 171, blue: 228) public static let mvmPurple33 = UIColor.assetColor(named: "purple33")
/// HEX: #B356C8 /// HEX: #B356C8
public static let mvmPurple66 = UIColor.color8Bits(red: 179, green: 86, blue: 200) public static let mvmPurple66 = UIColor.assetColor(named: "purple66")
/// HEX: #6C177F /// HEX: #6C177F
public static let mvmPurpleShade1 = UIColor.color8Bits(red: 108, green: 23, blue: 127) public static let mvmPurpleShade1 = UIColor.assetColor(named: "purpleShade1")
/// HEX: #4A0E58 /// HEX: #4A0E58
public static let mvmPurpleShade2 = UIColor.color8Bits(red: 74, green: 14, blue: 88) public static let mvmPurpleShade2 = UIColor.assetColor(named: "purpleShade2")
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Orange // MARK: - Orange
//-------------------------------------------------- //--------------------------------------------------
/// HEX: #ED7000 /// HEX: #ED7000
public static let mvmOrange = UIColor.color8Bits(red: 237, green: 112, blue: 0) public static let mvmOrange = UIColor.assetColor(named: "orange")
/// HEX: #CC4D0F /// HEX: #CC4D0F
public static let mvmOrangeAA = UIColor.color8Bits(red: 204, green: 77, blue: 15) public static let mvmOrangeAA = UIColor.assetColor(named: "orangeAA")
/// HEX: #F9D0AB /// HEX: #F9D0AB
public static let mvmOrange33 = UIColor.color8Bits(red: 249, green: 208, blue: 171) public static let mvmOrange33 = UIColor.assetColor(named: "orange33")
/// HEX: #F3A157 /// HEX: #F3A157
public static let mvmOrange66 = UIColor.color8Bits(red: 243, green: 161, blue: 87) public static let mvmOrange66 = UIColor.assetColor(named: "orange66")
/// HEX: #CB5F00 /// HEX: #CB5F00
public static let mvmOrangeShade1 = UIColor.color8Bits(red: 203, green: 95, blue: 0) public static let mvmOrangeShade1 = UIColor.assetColor(named: "orangeShade1")
/// HEX: #984700 /// HEX: #984700
public static let mvmOrangeShade2 = UIColor.color8Bits(red: 152, green: 71, blue: 0) public static let mvmOrangeShade2 = UIColor.assetColor(named: "orangeShade2")
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Green // MARK: - Green
//-------------------------------------------------- //--------------------------------------------------
/// HEX: #008330 /// HEX: #008330
public static let mvmGreen = UIColor.color8Bits(red: 0, green: 134, blue: 48) public static let mvmGreen = UIColor.assetColor(named: "green")
/// HEX: #ABE4BF /// HEX: #ABE4BF
public static let mvmGreen33 = UIColor.color8Bits(red: 171, green: 228, blue: 191) public static let mvmGreen33 = UIColor.assetColor(named: "green33")
/// HEX: #57C880 /// HEX: #57C880
public static let mvmGreen66 = UIColor.color8Bits(red: 87, green: 200, blue: 128) public static let mvmGreen66 = UIColor.assetColor(named: "green66")
/// HEX: #0F5B25 /// HEX: #0F5B25
public static let mvmGreenShade2 = UIColor.color8Bits(red: 15, green: 91, blue: 37) public static let mvmGreenShade2 = UIColor.assetColor(named: "greenShade2")
/// HEX: #00AC3E /// HEX: #00AC3E
public static let mvmGreenInverted = UIColor.color8Bits(red: 0, green: 172, blue: 62) public static let mvmGreenInverted = UIColor.assetColor(named: "greenInverted")
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Blue // MARK: - Blue
//-------------------------------------------------- //--------------------------------------------------
/// HEX: #0077B4 /// HEX: #0077B4
public static let mvmBlue = UIColor.color8Bits(red: 0, green: 119, blue: 180) public static let mvmBlue = UIColor.assetColor(named: "blue")
/// HEX: #ABD8EF /// HEX: #ABD8EF
public static let mvmBlue33 = UIColor.color8Bits(red: 171, green: 216, blue: 239) public static let mvmBlue33 = UIColor.assetColor(named: "blue33")
/// HEX: #57B1DF /// HEX: #57B1DF
public static let mvmBlue66 = UIColor.color8Bits(red: 87, green: 177, blue: 223) public static let mvmBlue66 = UIColor.assetColor(named: "blue66")
/// HEX: #136598 /// HEX: #136598
public static let mvmBlueShade1 = UIColor.color8Bits(red: 19, green: 101, blue: 152) public static let mvmBlueShade1 = UIColor.assetColor(named: "blueShade1")
/// HEX: #0B4467 /// HEX: #0B4467
public static let mvmBlueShade2 = UIColor.color8Bits(red: 11, green: 68, blue: 103) public static let mvmBlueShade2 = UIColor.assetColor(named: "blueShade2")
/// HEX: #0088CE /// HEX: #0088CE
public static let mvmBlueInverted = UIColor.color8Bits(red: 0, green: 136, blue: 206) public static let mvmBlueInverted = UIColor.assetColor(named: "blueInverted")
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Yellow // MARK: - Yellow
//-------------------------------------------------- //--------------------------------------------------
/// HEX: #FFBC3D /// HEX: #FFBC3D
public static let mvmYellow = UIColor.color8Bits(red: 255, green: 188, blue: 61) public static let mvmYellow = UIColor.assetColor(named: "yellow")
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Gray // MARK: - Gray
//-------------------------------------------------- //--------------------------------------------------
/// HEX: #F6F6F6 /// HEX: #F6F6F6
public static let mvmCoolGray1 = UIColor.grayscale(rgb: 246) public static let mvmCoolGray1 = UIColor.assetColor(named: "coolGray1")
/// HEX: #D8DADA /// HEX: #D8DADA
public static let mvmCoolGray3 = UIColor.color8Bits(red: 216, green: 218, blue: 218) public static let mvmCoolGray3 = UIColor.assetColor(named: "coolGray3")
/// HEX: #747676 /// HEX: #747676
public static let mvmCoolGray6 = UIColor.color8Bits(red: 116, green: 118, blue: 118) public static let mvmCoolGray6 = UIColor.assetColor(named: "coolGray6")
/// HEX: #333333 /// HEX: #333333
public static let mvmCoolGray10 = UIColor.grayscale(rgb: 51) public static let mvmCoolGray10 = UIColor.assetColor(named: "coolGray10")
//-------------------------------------------------- //--------------------------------------------------
// MARK: - VZ UP Brand // MARK: - VZ UP Brand
//-------------------------------------------------- //--------------------------------------------------
/// HEX: #F9D542 /// HEX: #F9D542
public static let vzupGold1 = UIColor.color8Bits(red: 249, green: 213, blue: 66) public static let vzupGold1 = UIColor.assetColor(named: "upGold1")
/// HEX: #F4CA53 /// HEX: #F4CA53
public static let vzupGold2 = UIColor.color8Bits(red: 244, green: 202, blue: 83) public static let vzupGold2 = UIColor.assetColor(named: "upGold2")
/// HEX: #CC9B2D /// HEX: #CC9B2D
public static let vzupGold3 = UIColor.color8Bits(red: 204, green: 155, blue: 45) public static let vzupGold3 = UIColor.assetColor(named: "upGold3")
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Functions // MARK: - Functions
//-------------------------------------------------- //--------------------------------------------------
public static func assetColor(named name: String) -> UIColor {
return UIColor(named: name, in: MVMCoreUIUtility.bundleForMVMCoreUI(), compatibleWith: nil)!
}
/// Convenience to get a grayscale UIColor where the same value is used for red, green, and blue. /// Convenience to get a grayscale UIColor where the same value is used for red, green, and blue.
public class func grayscale(rgb: Int, alpha: CGFloat = 1.0) -> UIColor { public class func grayscale(rgb: Int, alpha: CGFloat = 1.0) -> UIColor {
@ -299,7 +303,7 @@ extension UIColor {
} else if numberOfComponents == 2 { } else if numberOfComponents == 2 {
// Monochromatic color space // Monochromatic color space
let value = Int(CGFloat(components[0]) * 255) let value = Int(CGFloat(components[0]) * 255)
// If alpha of color is less than 1.0 then alpha hex is relevant. // If alpha of color is less than 1.0 then alpha hex is relevant.
if components[1] < 1.0 { if components[1] < 1.0 {
let alpha = Int(CGFloat(components[1]) * 255) let alpha = Int(CGFloat(components[1]) * 255)

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x00",
"alpha" : "1.000",
"blue" : "0xB4",
"green" : "0x77"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xAB",
"alpha" : "1.000",
"blue" : "0xEF",
"green" : "0xD8"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x57",
"alpha" : "1.000",
"blue" : "0xDF",
"green" : "0xB1"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x00",
"alpha" : "1.000",
"blue" : "0xCE",
"green" : "0x88"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x13",
"alpha" : "1.000",
"blue" : "0x98",
"green" : "0x65"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x0B",
"alpha" : "1.000",
"blue" : "0x67",
"green" : "0x44"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xF6",
"alpha" : "1.000",
"blue" : "0xF6",
"green" : "0xF6"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x33",
"alpha" : "1.000",
"blue" : "0x33",
"green" : "0x33"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xD8",
"alpha" : "1.000",
"blue" : "0xDA",
"green" : "0xDA"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x74",
"alpha" : "1.000",
"blue" : "0x76",
"green" : "0x76"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x00",
"alpha" : "1.000",
"blue" : "0x30",
"green" : "0x83"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xAB",
"alpha" : "1.000",
"blue" : "0xBF",
"green" : "0xE4"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x57",
"alpha" : "1.000",
"blue" : "0x80",
"green" : "0xC8"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x00",
"alpha" : "1.000",
"blue" : "0x3E",
"green" : "0xAC"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x0F",
"alpha" : "1.000",
"blue" : "0x25",
"green" : "0x5B"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xED",
"alpha" : "1.000",
"blue" : "0x00",
"green" : "0x70"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xF9",
"alpha" : "1.000",
"blue" : "0xAB",
"green" : "0xD0"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xF3",
"alpha" : "1.000",
"blue" : "0x57",
"green" : "0xA1"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xCC",
"alpha" : "1.000",
"blue" : "0x0F",
"green" : "0x4D"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xCB",
"alpha" : "1.000",
"blue" : "0x00",
"green" : "0x5F"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x98",
"alpha" : "1.000",
"blue" : "0x00",
"green" : "0x47"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xD9",
"alpha" : "1.000",
"blue" : "0x68",
"green" : "0x03"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xF2",
"alpha" : "1.000",
"blue" : "0xCD",
"green" : "0xAB"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xE6",
"alpha" : "1.000",
"blue" : "0x9B",
"green" : "0x58"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xB3",
"alpha" : "1.000",
"blue" : "0x63",
"green" : "0x1C"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x83",
"alpha" : "1.000",
"blue" : "0x42",
"green" : "0x08"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x8C",
"alpha" : "1.000",
"blue" : "0xAC",
"green" : "0x00"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xD9",
"alpha" : "1.000",
"blue" : "0xE4",
"green" : "0xAB"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xB3",
"alpha" : "1.000",
"blue" : "0xC8",
"green" : "0x56"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x6C",
"alpha" : "1.000",
"blue" : "0x7F",
"green" : "0x17"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x4A",
"alpha" : "1.000",
"blue" : "0x58",
"green" : "0x0E"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xD5",
"alpha" : "1.000",
"blue" : "0x1E",
"green" : "0x2B"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xF9",
"alpha" : "1.000",
"blue" : "0x42",
"green" : "0xD5"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xF4",
"alpha" : "1.000",
"blue" : "0x53",
"green" : "0xCA"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xCC",
"alpha" : "1.000",
"blue" : "0x2D",
"green" : "0x9B"
}
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xFF",
"alpha" : "1.000",
"blue" : "0x3D",
"green" : "0xBC"
}
}
}
]
}

View File

@ -43,6 +43,14 @@ import UIKit
return navigationController return navigationController
} }
/// Convenience function for setting the navigation item.
public static func setNavigationItem(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
viewController.navigationItem.title = navigationItemModel.title
viewController.navigationItem.accessibilityLabel = navigationItemModel.title
viewController.navigationItem.hidesBackButton = (navigationItemModel.backButton != nil)
setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
}
/// Convenience function for setting the navigation buttons. /// Convenience function for setting the navigation buttons.
public static func setNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) { public static func setNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
@ -70,11 +78,7 @@ import UIKit
} }
/// Convenience function for setting the navigation bar ui, except for the buttons. /// Convenience function for setting the navigation bar ui, except for the buttons.
public static func setNavigationUI(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) { public static func setNavigationBarUI(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
viewController.navigationItem.title = navigationItemModel.title
viewController.navigationItem.accessibilityLabel = navigationItemModel.title
viewController.navigationItem.hidesBackButton = (navigationItemModel.backButton != nil)
navigationController.setNavigationBarHidden(navigationItemModel.hidden, animated: true) navigationController.setNavigationBarHidden(navigationItemModel.hidden, animated: true)
navigationController.navigationBar.barTintColor = navigationItemModel.backgroundColor?.uiColor ?? .white navigationController.navigationBar.barTintColor = navigationItemModel.backgroundColor?.uiColor ?? .white
@ -90,17 +94,19 @@ import UIKit
} }
} }
/// Convenience function for setting navigation bar with model.
public static func set(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
setNavigationUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
}
/// Convenience setter for legacy files /// Convenience setter for legacy files
public static func set(navigationController: UINavigationController, navigationJSON: [String: Any], viewController: UIViewController) throws { public static func setNavigationItem(navigationController: UINavigationController, navigationJSON: [String: Any], viewController: UIViewController) throws {
guard let barModel = try MoleculeObjectMapping.shared()?.getMoleculeModelForJSON(navigationJSON) as? (MoleculeModelProtocol & NavigationItemModelProtocol) else { guard let barModel = try MoleculeObjectMapping.shared()?.getMoleculeModelForJSON(navigationJSON) as? (MoleculeModelProtocol & NavigationItemModelProtocol) else {
throw ModelRegistry.Error.decoderOther(message: "Model not a bar model") throw ModelRegistry.Error.decoderOther(message: "Model not a bar model")
} }
set(navigationController: navigationController, navigationItemModel: barModel, viewController: viewController) setNavigationItem(navigationController: navigationController, navigationItemModel: barModel, viewController: viewController)
}
/// Convenience setter for legacy files
public static func setNavigationBarUI(navigationController: UINavigationController, navigationJSON: [String: Any], viewController: UIViewController) throws {
guard let barModel = try MoleculeObjectMapping.shared()?.getMoleculeModelForJSON(navigationJSON) as? (MoleculeModelProtocol & NavigationItemModelProtocol) else {
throw ModelRegistry.Error.decoderOther(message: "Model not a bar model")
}
setNavigationBarUI(navigationController: navigationController, navigationItemModel: barModel, viewController: viewController)
} }
} }

View File

@ -15,7 +15,7 @@ public extension MVMCoreUISplitViewController {
guard let splitView = MVMCoreUISplitViewController.main(), guard let splitView = MVMCoreUISplitViewController.main(),
navigationController == splitView.navigationController, navigationController == splitView.navigationController,
navigationController.topViewController == viewController else { navigationController.topViewController == viewController else {
NavigationController.set(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) NavigationController.setNavigationBarUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
return return
} }
splitView.set(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel, leftPanelAccessible: leftPanelAccessible, rightPanelAccessible: rightPanelAccessible, progress: progress) splitView.set(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel, leftPanelAccessible: leftPanelAccessible, rightPanelAccessible: rightPanelAccessible, progress: progress)
@ -27,7 +27,7 @@ public extension MVMCoreUISplitViewController {
// Setup the panels. // Setup the panels.
setupPanels() setupPanels()
NavigationController.setNavigationUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) NavigationController.setNavigationBarUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
setLeftPanelIsAccessible(leftPanelAccessible ?? leftPanelIsAccessible, for: viewController, updateNavigationButtons: false) setLeftPanelIsAccessible(leftPanelAccessible ?? leftPanelIsAccessible, for: viewController, updateNavigationButtons: false)
setRightPanelIsAccessible(rightPanelAccessible ?? rightPanelIsAccessible, for: viewController, updateNavigationButtons: false) setRightPanelIsAccessible(rightPanelAccessible ?? rightPanelIsAccessible, for: viewController, updateNavigationButtons: false)
@ -117,7 +117,7 @@ public extension MVMCoreUISplitViewController {
guard let splitView = MVMCoreUISplitViewController.main(), guard let splitView = MVMCoreUISplitViewController.main(),
navigationController == splitView.navigationController, navigationController == splitView.navigationController,
navigationController.topViewController == viewController else { navigationController.topViewController == viewController else {
NavigationController.set(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) NavigationController.setNavigationBarUI(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController)
return return
} }
let progress = progress?.floatValue let progress = progress?.floatValue

View File

@ -17,8 +17,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)defaultLogPageStateForController:(nonnull id <MVMCoreViewControllerProtocol>)controller; - (void)defaultLogPageStateForController:(nonnull id <MVMCoreViewControllerProtocol>)controller;
// Action Logging // Action Logging
- (void)defaultLogActionForController:(nonnull id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData; - (void)defaultLogActionForController:(nullable id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
- (nullable NSDictionary *)defaultGetActionTrackDataDictionaryForController:(nonnull id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData; - (nullable NSDictionary *)defaultGetActionTrackDataDictionaryForController:(nullable id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
@end @end

View File

@ -13,10 +13,10 @@
- (void)defaultLogPageStateForController:(nonnull id <MVMCoreViewControllerProtocol>)controller { - (void)defaultLogPageStateForController:(nonnull id <MVMCoreViewControllerProtocol>)controller {
} }
- (void)defaultLogActionForController:(nonnull id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData { - (void)defaultLogActionForController:(nullable id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData {
} }
- (nullable NSDictionary *)defaultGetActionTrackDataDictionaryForController:(nonnull id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData { - (nullable NSDictionary *)defaultGetActionTrackDataDictionaryForController:(nullable id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData {
return nil; return nil;
} }

View File

@ -10,6 +10,7 @@
"AccCloseButton" = "Close"; "AccCloseButton" = "Close";
"swipe_to_select_with_action_hint" = "swipe up or down to select action, then double tap to select."; "swipe_to_select_with_action_hint" = "swipe up or down to select action, then double tap to select.";
"AccDisabled" = "Disabled"; "AccDisabled" = "Disabled";
"index_string_of_total" = "%@ of %d";
// MARK: Tab // MARK: Tab
"AccTab" = ", tab"; "AccTab" = ", tab";
@ -59,7 +60,6 @@
"radio_not_selected_state" = "Not Selected"; "radio_not_selected_state" = "Not Selected";
"radio_desc_state" = "Option"; "radio_desc_state" = "Option";
// MARK: Switch / Toggle // MARK: Switch / Toggle
"mfswitch_buttonlabel" = "Switch Button"; "mfswitch_buttonlabel" = "Switch Button";
"Toggle_buttonlabel" = "Toggle Button"; "Toggle_buttonlabel" = "Toggle Button";

View File

@ -9,6 +9,7 @@
// Accessibility // Accessibility
"swipe_to_select_with_action_hint" = "deslízate hacia arriba o hacia abajo para seleccionar la acción, luego toca dos veces para seleccionar."; "swipe_to_select_with_action_hint" = "deslízate hacia arriba o hacia abajo para seleccionar la acción, luego toca dos veces para seleccionar.";
"AccDisabled" = "desactivado"; "AccDisabled" = "desactivado";
"index_string_of_total" = "%@ de %d";
"AccCloseButton" = "Cerrar"; "AccCloseButton" = "Cerrar";
// Tab // Tab

View File

@ -9,6 +9,7 @@
// Accessibility // Accessibility
"swipe_to_select_with_action_hint" = "deslízate hacia arriba o hacia abajo para seleccionar la acción, luego toca dos veces para seleccionar."; "swipe_to_select_with_action_hint" = "deslízate hacia arriba o hacia abajo para seleccionar la acción, luego toca dos veces para seleccionar.";
"AccDisabled" = "desactivado"; "AccDisabled" = "desactivado";
"index_string_of_total" = "%@ de %d";
"AccCloseButton" = "Cerrar"; "AccCloseButton" = "Cerrar";
// Tab // Tab

View File

@ -374,6 +374,7 @@
weakSelf.shortViewHeight.active = NO; weakSelf.shortViewHeight.active = NO;
} completion:^(BOOL finished) { } completion:^(BOOL finished) {
[weakSelf.viewToLayout layoutIfNeeded]; [weakSelf.viewToLayout layoutIfNeeded];
weakSelf.accessibilityElements = @[weakSelf.shortView.label];
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil); UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);
[MVMCoreDispatchUtility performBlockInBackground:^{ [MVMCoreDispatchUtility performBlockInBackground:^{
// Must notify animation delegate when animating finished. // Must notify animation delegate when animating finished.

View File

@ -46,6 +46,9 @@ NS_ASSUME_NONNULL_BEGIN
// Removes any format. // Removes any format.
+ (nullable NSString *)removeMdnFormat:(nullable NSString *)mdn; + (nullable NSString *)removeMdnFormat:(nullable NSString *)mdn;
/// Returns an ordinal formatted string for a number.
+ (nullable NSString *)getOrdinalStringForIndex:(nonnull NSNumber *)number;
#pragma mark - Validations #pragma mark - Validations
// Will validate passed string on corresponding regular expression // Will validate passed string on corresponding regular expression

View File

@ -113,6 +113,12 @@
return mdn; return mdn;
} }
+ (nullable NSString *)getOrdinalStringForIndex:(nonnull NSNumber *)number {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterOrdinalStyle;
return [formatter stringFromNumber:number];
}
#pragma mark - Validations #pragma mark - Validations
+ (BOOL)validateString:(nonnull NSString *)string withRegularExpression:(nonnull NSString *)regExpression { + (BOOL)validateString:(nonnull NSString *)string withRegularExpression:(nonnull NSString *)regExpression {