Merge branch 'develop' into feature/list_twocolumn_dropdownselectors
* develop: (41 commits) Image fixes Two link fixes Two Link delegateing using new toolbar enode additional check altered isEditable to editable to align with android latest state of text view removing Line model change. Implemented Scott feedback managing hidden border further developmet of textView. little fixes and delegate updates. reverting set method super call in Line. remove extra registry functioning border revised how fields clear themselves aligning with android changes updating to align with android. changing super. three layer fill ...
This commit is contained in:
commit
bd1ccb251c
@ -88,6 +88,8 @@
|
||||
0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */; };
|
||||
0A6682AA2435125F00AD3CA1 /* Styler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682A92435125F00AD3CA1 /* Styler.swift */; };
|
||||
0A6682AC243531C300AD3CA1 /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682AB243531C300AD3CA1 /* Padding.swift */; };
|
||||
0A6682B5243769C700AD3CA1 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682B3243769C700AD3CA1 /* TextView.swift */; };
|
||||
0A6682B6243769C700AD3CA1 /* TextViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682B4243769C700AD3CA1 /* TextViewModel.swift */; };
|
||||
0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */; };
|
||||
0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; };
|
||||
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; };
|
||||
@ -213,6 +215,8 @@
|
||||
AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; };
|
||||
BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */; };
|
||||
BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */; };
|
||||
BB2BF0EA2452A9BB001D0FC2 /* ListDeviceComplexButtonSmall.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2BF0E92452A9BB001D0FC2 /* ListDeviceComplexButtonSmall.swift */; };
|
||||
BB2BF0EC2452A9D5001D0FC2 /* ListDeviceComplexButtonSmallModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2BF0EB2452A9D5001D0FC2 /* ListDeviceComplexButtonSmallModel.swift */; };
|
||||
BB2C968F24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */; };
|
||||
BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */; };
|
||||
BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */; };
|
||||
@ -280,6 +284,8 @@
|
||||
D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; };
|
||||
D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; };
|
||||
D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; };
|
||||
D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9B245874F8002DE544 /* BGImageMolecule.swift */; };
|
||||
D253BB9E2458751F002DE544 /* BGImageMoleculeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */; };
|
||||
D256E9932412880000360572 /* Header.swift in Sources */ = {isa = PBXBuildFile; fileRef = D256E9922412880000360572 /* Header.swift */; };
|
||||
D260105323CEA61600764D80 /* ToggleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260105223CEA61600764D80 /* ToggleModel.swift */; };
|
||||
D260105923D0A92900764D80 /* ContainerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260105823D0A92900764D80 /* ContainerProtocol.swift */; };
|
||||
@ -311,6 +317,10 @@
|
||||
D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */; };
|
||||
D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */; };
|
||||
D282AACB2243C61700C46919 /* ButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AACA2243C61700C46919 /* ButtonView.swift */; };
|
||||
D28764AA2458980300CB882D /* ThreeLayerFillMiddleTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28764A92458980300CB882D /* ThreeLayerFillMiddleTemplate.swift */; };
|
||||
D28764AC245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28764AB245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift */; };
|
||||
D28764F9245A327200CB882D /* TwoLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28764F8245A327200CB882D /* TwoLinkView.swift */; };
|
||||
D28764FB245A33A500CB882D /* TwoLinkViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28764FA245A33A500CB882D /* TwoLinkViewModel.swift */; };
|
||||
D28A837923C7D5BC00DFE4FC /* PageModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837823C7D5BC00DFE4FC /* PageModelProtocol.swift */; };
|
||||
D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837A23C928DA00DFE4FC /* MoleculeListCellProtocol.swift */; };
|
||||
D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837C23CCA86A00DFE4FC /* TabsListItemModel.swift */; };
|
||||
@ -542,6 +552,8 @@
|
||||
0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonBodyTextModel.swift; sourceTree = "<group>"; };
|
||||
0A6682A92435125F00AD3CA1 /* Styler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Styler.swift; sourceTree = "<group>"; };
|
||||
0A6682AB243531C300AD3CA1 /* Padding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Padding.swift; sourceTree = "<group>"; };
|
||||
0A6682B3243769C700AD3CA1 /* TextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = "<group>"; };
|
||||
0A6682B4243769C700AD3CA1 /* TextViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextViewModel.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>"; };
|
||||
0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = "<group>"; };
|
||||
@ -669,6 +681,8 @@
|
||||
AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.swift; sourceTree = "<group>"; };
|
||||
BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMediumModel.swift; sourceTree = "<group>"; };
|
||||
BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMedium.swift; sourceTree = "<group>"; };
|
||||
BB2BF0E92452A9BB001D0FC2 /* ListDeviceComplexButtonSmall.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonSmall.swift; sourceTree = "<group>"; };
|
||||
BB2BF0EB2452A9D5001D0FC2 /* ListDeviceComplexButtonSmallModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonSmallModel.swift; sourceTree = "<group>"; };
|
||||
BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
||||
BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinks.swift; sourceTree = "<group>"; };
|
||||
BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsectionModel.swift; sourceTree = "<group>"; };
|
||||
@ -736,6 +750,8 @@
|
||||
D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = "<group>"; };
|
||||
D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = "<group>"; };
|
||||
D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = "<group>"; };
|
||||
D253BB9B245874F8002DE544 /* BGImageMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMolecule.swift; sourceTree = "<group>"; };
|
||||
D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMoleculeModel.swift; sourceTree = "<group>"; };
|
||||
D256E9922412880000360572 /* Header.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Header.swift; sourceTree = "<group>"; };
|
||||
D260105223CEA61600764D80 /* ToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleModel.swift; sourceTree = "<group>"; };
|
||||
D260105823D0A92900764D80 /* ContainerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerProtocol.swift; sourceTree = "<group>"; };
|
||||
@ -766,6 +782,10 @@
|
||||
D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFLoadImageView.swift; sourceTree = "<group>"; };
|
||||
D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFTransparentGIFView.swift; sourceTree = "<group>"; };
|
||||
D282AACA2243C61700C46919 /* ButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonView.swift; sourceTree = "<group>"; };
|
||||
D28764A92458980300CB882D /* ThreeLayerFillMiddleTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerFillMiddleTemplate.swift; sourceTree = "<group>"; };
|
||||
D28764AB245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerFillMiddleTemplateModel.swift; sourceTree = "<group>"; };
|
||||
D28764F8245A327200CB882D /* TwoLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoLinkView.swift; sourceTree = "<group>"; };
|
||||
D28764FA245A33A500CB882D /* TwoLinkViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoLinkViewModel.swift; sourceTree = "<group>"; };
|
||||
D28A837823C7D5BC00DFE4FC /* PageModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageModelProtocol.swift; sourceTree = "<group>"; };
|
||||
D28A837A23C928DA00DFE4FC /* MoleculeListCellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeListCellProtocol.swift; sourceTree = "<group>"; };
|
||||
D28A837C23CCA86A00DFE4FC /* TabsListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsListItemModel.swift; sourceTree = "<group>"; };
|
||||
@ -1023,10 +1043,10 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */,
|
||||
D29E28DE23D740FC00ACEA85 /* Container */,
|
||||
D2D90B432404789000DD6EC9 /* MoleculeContainerProtocol.swift */,
|
||||
014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */,
|
||||
D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */,
|
||||
D260105823D0A92900764D80 /* ContainerProtocol.swift */,
|
||||
D29E28DC23D7404C00ACEA85 /* ContainerHelper.swift */,
|
||||
014AA72223C501E2006F3E93 /* ContainerModel.swift */,
|
||||
D243859823A16B1800332775 /* Container.swift */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
@ -1202,6 +1222,8 @@
|
||||
D20FFFB42451E32100A31DA2 /* Device */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BB2BF0EB2452A9D5001D0FC2 /* ListDeviceComplexButtonSmallModel.swift */,
|
||||
BB2BF0E92452A9BB001D0FC2 /* ListDeviceComplexButtonSmall.swift */,
|
||||
BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */,
|
||||
BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */,
|
||||
AA617AB12453012400910B8F /* ListDeviceComplexLinkSmallModel.swift */,
|
||||
@ -1343,6 +1365,8 @@
|
||||
94F6516C2437954100631BF9 /* Tabs.swift */,
|
||||
011D9625240EBB16000E3791 /* RadioButtonLabelModel.swift */,
|
||||
017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */,
|
||||
D28764FA245A33A500CB882D /* TwoLinkViewModel.swift */,
|
||||
D28764F8245A327200CB882D /* TwoLinkView.swift */,
|
||||
);
|
||||
path = HorizontalCombinationViews;
|
||||
sourceTree = "<group>";
|
||||
@ -1492,6 +1516,22 @@
|
||||
path = TwoColumn;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D253BB9A24587023002DE544 /* OtherContainers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D2D90B432404789000DD6EC9 /* MoleculeContainerProtocol.swift */,
|
||||
014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */,
|
||||
D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */,
|
||||
D28A838423CCCA8900DFE4FC /* ScrollerModel.swift */,
|
||||
D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */,
|
||||
012A88C5238DA34000FE3DA1 /* ModuleMoleculeModel.swift */,
|
||||
D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */,
|
||||
D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */,
|
||||
D253BB9B245874F8002DE544 /* BGImageMolecule.swift */,
|
||||
);
|
||||
path = OtherContainers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D260105723CF9CC500764D80 /* Doughnut */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1585,6 +1625,8 @@
|
||||
D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */,
|
||||
D2092350244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift */,
|
||||
D209234E244F77FD0044AD09 /* ThreeLayerCenterTemplate.swift */,
|
||||
D28764AB245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift */,
|
||||
D28764A92458980300CB882D /* ThreeLayerFillMiddleTemplate.swift */,
|
||||
D264FAA4243F66A500D98315 /* CollectionTemplateItemProtocol.swift */,
|
||||
D264FA8B243BCD8E00D98315 /* CollectionTemplateModel.swift */,
|
||||
D264FA8D243BCD9A00D98315 /* CollectionTemplate.swift */,
|
||||
@ -1615,6 +1657,7 @@
|
||||
D29DF10E21E67A77003B2FB9 /* Molecules */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D253BB9A24587023002DE544 /* OtherContainers */,
|
||||
D22B38E923F4E07800490EF6 /* DesignedComponents */,
|
||||
D22479912316A9EF003FCCF9 /* Items */,
|
||||
D224798F2316A99F003FCCF9 /* LeftRightViews */,
|
||||
@ -1626,10 +1669,6 @@
|
||||
D2A514662213885800345BFB /* MoleculeHeaderView.swift */,
|
||||
012A88EB238F084D00FE3DA1 /* FooterModel.swift */,
|
||||
D274CA322236A78900B01B62 /* FooterView.swift */,
|
||||
012A88C5238DA34000FE3DA1 /* ModuleMoleculeModel.swift */,
|
||||
D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */,
|
||||
D28A838423CCCA8900DFE4FC /* ScrollerModel.swift */,
|
||||
D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */,
|
||||
D260105723CF9CC500764D80 /* Doughnut */,
|
||||
D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */,
|
||||
);
|
||||
@ -1925,20 +1964,11 @@
|
||||
path = StringAndMoleculeStack;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D29E28DE23D740FC00ACEA85 /* Container */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
014AA72223C501E2006F3E93 /* ContainerModel.swift */,
|
||||
D260105823D0A92900764D80 /* ContainerProtocol.swift */,
|
||||
D243859823A16B1800332775 /* Container.swift */,
|
||||
D29E28DC23D7404C00ACEA85 /* ContainerHelper.swift */,
|
||||
);
|
||||
path = Container;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D2B18B7D236090D500A9AEDC /* BaseClasses */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0A6682B4243769C700AD3CA1 /* TextViewModel.swift */,
|
||||
0A6682B3243769C700AD3CA1 /* TextView.swift */,
|
||||
C003506023AA94CD00B6AC29 /* Button.swift */,
|
||||
D2B18B7E2360913400A9AEDC /* Control.swift */,
|
||||
D2B18B802360945C00A9AEDC /* View.swift */,
|
||||
@ -2162,13 +2192,16 @@
|
||||
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */,
|
||||
D2FB151D23A40F1500C20E10 /* MoleculeStackItem.swift in Sources */,
|
||||
AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */,
|
||||
D28764AA2458980300CB882D /* ThreeLayerFillMiddleTemplate.swift in Sources */,
|
||||
D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */,
|
||||
0116A4E5228B19640094F3ED /* RadioButtonSelectionHelper.swift in Sources */,
|
||||
D2092353244F7D630044AD09 /* MVMCoreUIViewControllerMappingObject+Extension.swift in Sources */,
|
||||
017BEB48236230DB0024EF95 /* MoleculeViewProtocol.swift in Sources */,
|
||||
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */,
|
||||
94382086243238D100B43AF3 /* WebViewModel.swift in Sources */,
|
||||
D28764F9245A327200CB882D /* TwoLinkView.swift in Sources */,
|
||||
D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */,
|
||||
0A6682B5243769C700AD3CA1 /* TextView.swift in Sources */,
|
||||
D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */,
|
||||
D21B7F602437C5BC00051ABF /* MoleculeStackView.swift in Sources */,
|
||||
0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */,
|
||||
@ -2182,6 +2215,7 @@
|
||||
D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */,
|
||||
D2B18B7F2360913400A9AEDC /* Control.swift in Sources */,
|
||||
011D95A924057AC7000E3791 /* FormGroupWatcherFieldProtocol.swift in Sources */,
|
||||
BB2BF0EA2452A9BB001D0FC2 /* ListDeviceComplexButtonSmall.swift in Sources */,
|
||||
D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */,
|
||||
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */,
|
||||
D29DF12F21E6851E003B2FB9 /* MVMCoreUITopAlertMainView.m in Sources */,
|
||||
@ -2212,6 +2246,7 @@
|
||||
AA617AB22453012400910B8F /* ListDeviceComplexLinkSmallModel.swift in Sources */,
|
||||
D260106323D0C05000764D80 /* StackItemModel.swift in Sources */,
|
||||
D2E2A99823D8D63C000B42E6 /* ActionDetailWithImageModel.swift in Sources */,
|
||||
D28764AC245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift in Sources */,
|
||||
BBBBC87D24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift in Sources */,
|
||||
D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */,
|
||||
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */,
|
||||
@ -2258,6 +2293,7 @@
|
||||
AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */,
|
||||
011D9626240EBB16000E3791 /* RadioButtonLabelModel.swift in Sources */,
|
||||
8DDD6C1D244D90B8006A2232 /* ListThreeColumnDataUsage.swift in Sources */,
|
||||
D28764FB245A33A500CB882D /* TwoLinkViewModel.swift in Sources */,
|
||||
AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */,
|
||||
D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */,
|
||||
944589232385DA9600DE9FD4 /* ImageViewModel.swift in Sources */,
|
||||
@ -2371,6 +2407,7 @@
|
||||
D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */,
|
||||
012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */,
|
||||
D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */,
|
||||
0A6682B6243769C700AD3CA1 /* TextViewModel.swift in Sources */,
|
||||
9445890E2385C3F800DE9FD4 /* MultiProgressModel.swift in Sources */,
|
||||
011D95A5240455DC000E3791 /* FormGroupRule.swift in Sources */,
|
||||
D2A6390522CBCE160052ED1F /* MoleculeCollectionViewCell.swift in Sources */,
|
||||
@ -2388,6 +2425,7 @@
|
||||
AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */,
|
||||
522679C223FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift in Sources */,
|
||||
8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */,
|
||||
D253BB9E2458751F002DE544 /* BGImageMoleculeModel.swift in Sources */,
|
||||
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */,
|
||||
8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */,
|
||||
BBAA4F03243D8E3B005AAD5F /* RadioBoxes.swift in Sources */,
|
||||
@ -2411,6 +2449,7 @@
|
||||
D2092355244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift in Sources */,
|
||||
0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
|
||||
0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */,
|
||||
D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */,
|
||||
D29DF17B21E69E1F003B2FB9 /* PrimaryButton.m in Sources */,
|
||||
D2C78CD224228BBD00B69FDE /* ActionOpenPanelModel.swift in Sources */,
|
||||
AA617AB02453010A00910B8F /* ListDeviceComplexLinkSmall.swift in Sources */,
|
||||
@ -2446,6 +2485,7 @@
|
||||
AA85236C244435A20059CC1E /* RadioSwatchCollectionViewCell.swift in Sources */,
|
||||
52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */,
|
||||
D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */,
|
||||
BB2BF0EC2452A9D5001D0FC2 /* ListDeviceComplexButtonSmallModel.swift in Sources */,
|
||||
0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */,
|
||||
94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */,
|
||||
943784F6236B77BB006A1E82 /* WheelAnimationHandler.swift in Sources */,
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
@objcMembers public class BaseDropdownEntryFieldModel: TextEntryFieldModel {
|
||||
@objcMembers open class BaseDropdownEntryFieldModel: TextEntryFieldModel {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
@objcMembers public class DateDropdownEntryFieldModel: BaseDropdownEntryFieldModel {
|
||||
@objcMembers open class DateDropdownEntryFieldModel: BaseDropdownEntryFieldModel {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -13,7 +13,7 @@ import UIKit
|
||||
}
|
||||
|
||||
|
||||
@objcMembers open class DigitBox: EntryFieldContainer, UITextFieldDelegate, TextFieldDidDeleteProtocol {
|
||||
@objcMembers open class DigitBox: EntryFieldContainer, UITextFieldDelegate, TextInputDidDeleteProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
@ -24,7 +24,7 @@ import UIKit
|
||||
textField.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
textField.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||
textField.textAlignment = .center
|
||||
textField.font = MFStyler.fontForTextField()
|
||||
textField.font = Styler.Font.RegularBodyLarge.getFont()
|
||||
textField.keyboardType = .numberPad
|
||||
return textField
|
||||
}()
|
||||
@ -48,11 +48,11 @@ import UIKit
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.borderStrokeColor = error ? .mfPumpkin() : .mfSilver()
|
||||
self.borderStrokeColor = error ? .mvmOrange : .mvmCoolGray3
|
||||
|
||||
let barHeight: CGFloat = self.showError ? 4 : 1
|
||||
self.bottomBar?.frame = CGRect(x: 0, y: self.bounds.height - barHeight, width: self.bounds.width, height: barHeight)
|
||||
self.bottomBar?.backgroundColor = self.showError ? UIColor.mfPumpkin().cgColor : UIColor.black.cgColor
|
||||
self.bottomBar?.backgroundColor = self.showError ? UIColor.mvmOrange.cgColor : UIColor.mvmBlack.cgColor
|
||||
|
||||
self.setNeedsDisplay()
|
||||
self.layoutIfNeeded()
|
||||
@ -97,29 +97,24 @@ import UIKit
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
|
||||
guard constraints.isEmpty else { return }
|
||||
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
backgroundColor = .clear
|
||||
|
||||
|
||||
addSubview(digitField)
|
||||
digitField.delegate = self
|
||||
digitField.didDeleteDelegate = self
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
digitField.topAnchor.constraint(equalTo: topAnchor, constant: PaddingOne),
|
||||
digitField.leadingAnchor.constraint(equalTo: leadingAnchor, constant: PaddingOne),
|
||||
bottomAnchor.constraint(equalTo: digitField.bottomAnchor, constant: PaddingOne),
|
||||
trailingAnchor.constraint(equalTo: digitField.trailingAnchor, constant: PaddingOne),
|
||||
digitField.centerYAnchor.constraint(equalTo: centerYAnchor),
|
||||
digitField.centerXAnchor.constraint(equalTo: centerXAnchor)])
|
||||
|
||||
widthConstraint = widthAnchor.constraint(equalToConstant: DigitBox.size.width)
|
||||
widthConstraint?.isActive = true
|
||||
heightConstraint = heightAnchor.constraint(equalToConstant: DigitBox.size.height)
|
||||
heightConstraint?.isActive = true
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
digitField.topAnchor.constraint(equalTo: topAnchor, constant: Padding.Three),
|
||||
digitField.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
bottomAnchor.constraint(equalTo: digitField.bottomAnchor, constant: Padding.Three),
|
||||
trailingAnchor.constraint(equalTo: digitField.trailingAnchor),
|
||||
digitField.centerYAnchor.constraint(equalTo: centerYAnchor)
|
||||
])
|
||||
|
||||
if let bottomBar = bottomBar {
|
||||
layer.addSublayer(bottomBar)
|
||||
}
|
||||
@ -130,7 +125,7 @@ import UIKit
|
||||
updateView(MVMCoreUIUtility.getWidth())
|
||||
}
|
||||
|
||||
@objc public func textFieldDidDelete() {
|
||||
@objc public func textInputDidDelete() {
|
||||
|
||||
digitBoxDelegate?.digitFieldDidDelete?(digitField)
|
||||
}
|
||||
@ -146,7 +141,7 @@ import UIKit
|
||||
super.reset()
|
||||
|
||||
backgroundColor = .clear
|
||||
digitField.font = MFStyler.fontForTextField()
|
||||
digitField.font = Styler.Font.RegularBodyLarge.getFont()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -186,7 +181,7 @@ import UIKit
|
||||
sizeObject?.performBlockBase(onSize: size)
|
||||
widthConstraint?.constant = width
|
||||
heightConstraint?.constant = height
|
||||
digitField.font = MFFonts.mfFont55Rg(pointSize)
|
||||
digitField.font = MFFonts.mfFontDSRegular(pointSize)
|
||||
previousSize = size
|
||||
}
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@ import UIKit
|
||||
digitBoxes.append(newDigitBox)
|
||||
}
|
||||
|
||||
self.digitBoxes.forEach { $0.removeFromSuperview() }
|
||||
self.digitBoxes = digitBoxes
|
||||
guard let space = MFSizeObject(standardSize: 5, smalliPhoneSize: 3)?.getValueBasedOnScreenSize() else { return }
|
||||
|
||||
@ -76,6 +77,10 @@ import UIKit
|
||||
public var digitBoxes: [DigitBox] = []
|
||||
private var selectedDigitBox: DigitBox?
|
||||
|
||||
public var digitEntryModel: DigitEntryFieldModel? {
|
||||
return model as? DigitEntryFieldModel
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Computed Properties
|
||||
//--------------------------------------------------
|
||||
@ -224,14 +229,24 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
|
||||
@objc open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
|
||||
entryFieldContainer.disableAllBorders = true
|
||||
|
||||
if !self.digitBoxes.isEmpty {
|
||||
self.digitBoxes.forEach { $0.updateView(size) }
|
||||
}
|
||||
layoutIfNeeded()
|
||||
|
||||
super.updateView(size)
|
||||
}
|
||||
|
||||
public override func reset() {
|
||||
super.reset()
|
||||
|
||||
accessibilityElements = nil
|
||||
switchFieldsAutomatically = false
|
||||
selectedDigitBox = nil
|
||||
text = ""
|
||||
digitBoxes.forEach { $0.digitField.text = "" }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -326,7 +341,7 @@ import UIKit
|
||||
}
|
||||
|
||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
|
||||
guard let model = model as? DigitEntryFieldModel else { return }
|
||||
|
||||
numberOfDigits = model.digits
|
||||
@ -341,7 +356,7 @@ import UIKit
|
||||
$0.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate,
|
||||
action: #selector(observingDelegate.dismissFieldInput))
|
||||
}
|
||||
|
||||
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
@ -378,12 +393,14 @@ extension DigitEntryField {
|
||||
|
||||
// One character, switch old value with new, select next textfield
|
||||
textField.text = string
|
||||
digitEntryModel?.text = text
|
||||
selectNextDigitField(textField, clear: false)
|
||||
return false
|
||||
|
||||
} else if replacementLength == 0 && oldLength == 1 {
|
||||
// Non empty cell, clear and stay.
|
||||
textField.text = ""
|
||||
digitEntryModel?.text = text
|
||||
return false
|
||||
}
|
||||
|
||||
@ -410,6 +427,7 @@ extension DigitEntryField {
|
||||
|
||||
if !switchFieldsAutomatically {
|
||||
textField.text = ""
|
||||
digitEntryModel?.text = text
|
||||
}
|
||||
|
||||
proprietorTextDelegate?.textFieldDidBeginEditing?(textField)
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
|
||||
@objcMembers public class DigitEntryFieldModel: TextEntryFieldModel {
|
||||
@objcMembers open class DigitEntryFieldModel: TextEntryFieldModel {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -60,6 +60,7 @@ import UIKit
|
||||
self.titleLabel.textColor = enabled ? .mvmBlack : .mvmCoolGray3
|
||||
self.feedbackLabel.textColor = enabled ? .mvmBlack : .mvmCoolGray3
|
||||
self.entryFieldContainer.isEnabled = enabled
|
||||
self.entryFieldModel?.enabled = enabled
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +70,7 @@ import UIKit
|
||||
set (error) {
|
||||
self.feedback = error ? entryFieldModel?.errorMessage : entryFieldModel?.feedback
|
||||
self.entryFieldContainer.showError = error
|
||||
self.entryFieldModel?.showError = error
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,6 +79,7 @@ import UIKit
|
||||
get { return entryFieldContainer.isLocked }
|
||||
set (locked) {
|
||||
self.entryFieldContainer.isLocked = locked
|
||||
self.entryFieldModel?.locked = locked
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,6 +88,7 @@ import UIKit
|
||||
get { return entryFieldContainer.isSelected }
|
||||
set (selected) {
|
||||
self.entryFieldContainer.isSelected = selected
|
||||
self.entryFieldModel?.selected = selected
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,11 +261,13 @@ import UIKit
|
||||
if let isLocked = model.locked {
|
||||
self.isLocked = isLocked
|
||||
|
||||
} else if let isSelected = model.selected {
|
||||
self.isSelected = isSelected
|
||||
} else if (model.selected ?? false) && !model.wasInitiallySelected {
|
||||
|
||||
model.wasInitiallySelected = true
|
||||
self.isSelected = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 115
|
||||
}
|
||||
|
||||
@ -9,8 +9,7 @@
|
||||
import Foundation
|
||||
|
||||
|
||||
@objcMembers public class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, EnableableModelProtocol {
|
||||
|
||||
@objcMembers open class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, EnableableModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
@ -24,12 +23,14 @@ import Foundation
|
||||
public var feedback: String?
|
||||
public var errorMessage: String?
|
||||
public var enabled: Bool = true
|
||||
public var showError: Bool?
|
||||
public var locked: Bool?
|
||||
public var selected: Bool?
|
||||
public var text: String?
|
||||
public var fieldKey: String?
|
||||
public var groupName: String = FormValidator.defaultGroupName
|
||||
public var baseValue: AnyHashable?
|
||||
public var wasInitiallySelected: Bool = false
|
||||
|
||||
public var isValid: Bool? {
|
||||
didSet { updateUI?() }
|
||||
@ -51,6 +52,7 @@ import Foundation
|
||||
case errorMessage
|
||||
case locked
|
||||
case selected
|
||||
case showError
|
||||
case text
|
||||
case fieldKey
|
||||
case groupName
|
||||
@ -93,6 +95,7 @@ import Foundation
|
||||
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
||||
baseValue = text
|
||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||
|
||||
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||
self.groupName = groupName
|
||||
}
|
||||
@ -106,6 +109,7 @@ import Foundation
|
||||
try container.encodeIfPresent(feedback, forKey: .feedback)
|
||||
try container.encodeIfPresent(text, forKey: .text)
|
||||
try container.encodeIfPresent(locked, forKey: .locked)
|
||||
try container.encodeIfPresent(showError, forKey: .showError)
|
||||
try container.encodeIfPresent(selected, forKey: .selected)
|
||||
try container.encodeIfPresent(errorMessage, forKey: .errorMessage)
|
||||
try container.encode(enabled, forKey: .enabled)
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
@objcMembers public class ItemDropdownEntryFieldModel: BaseDropdownEntryFieldModel {
|
||||
@objcMembers open class ItemDropdownEntryFieldModel: BaseDropdownEntryFieldModel {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
@objcMembers public class MdnEntryFieldModel: TextEntryFieldModel {
|
||||
@objcMembers open class MdnEntryFieldModel: TextEntryFieldModel {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -134,7 +134,7 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
/// If you're using a MFViewController, you must set this to it
|
||||
/// If you're using a ViewController, you must set this to it
|
||||
public weak var uiTextFieldDelegate: UITextFieldDelegate? {
|
||||
get { return textField.delegate }
|
||||
set { textField.delegate = newValue }
|
||||
@ -339,6 +339,10 @@ import UIKit
|
||||
uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate
|
||||
observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate
|
||||
setupTextFieldToolbar()
|
||||
|
||||
if isSelected {
|
||||
startEditing()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
|
||||
@objcMembers public class TextEntryFieldModel: EntryFieldModel {
|
||||
@objcMembers open class TextEntryFieldModel: EntryFieldModel {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Types
|
||||
//--------------------------------------------------
|
||||
@ -17,6 +17,7 @@
|
||||
case secure
|
||||
case number
|
||||
case email
|
||||
case text
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -37,7 +38,6 @@
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case placeholder
|
||||
case enabledTextColor
|
||||
case disabledTextColor
|
||||
@ -66,7 +66,6 @@
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeIfPresent(placeholder, forKey: .placeholder)
|
||||
try container.encode(enabledTextColor, forKey: .enabledTextColor)
|
||||
try container.encode(disabledTextColor, forKey: .disabledTextColor)
|
||||
|
||||
@ -14,23 +14,36 @@ import UIKit
|
||||
}
|
||||
|
||||
public var heightConstraint: NSLayoutConstraint?
|
||||
public var widthConstraint: NSLayoutConstraint?
|
||||
|
||||
open func updateLineConstraints(constant: CGFloat) {
|
||||
if let useVerticalLine = lineModel?.useVerticalLine, useVerticalLine {
|
||||
heightConstraint?.isActive = false
|
||||
widthConstraint?.isActive = true
|
||||
widthConstraint?.constant = constant
|
||||
} else {
|
||||
widthConstraint?.isActive = false
|
||||
heightConstraint?.isActive = true
|
||||
heightConstraint?.constant = constant
|
||||
}
|
||||
}
|
||||
|
||||
open func setStyle(_ style: LineModel.Style) {
|
||||
switch style {
|
||||
case .standard:
|
||||
heightConstraint?.constant = 1
|
||||
backgroundColor = .mfSilver()
|
||||
updateLineConstraints(constant: 1)
|
||||
backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mfSilver()
|
||||
case .thin:
|
||||
heightConstraint?.constant = 1
|
||||
backgroundColor = .black
|
||||
updateLineConstraints(constant: 1)
|
||||
backgroundColor = lineModel?.backgroundColor?.uiColor ?? .black
|
||||
case .medium:
|
||||
heightConstraint?.constant = 2
|
||||
backgroundColor = .black
|
||||
updateLineConstraints(constant: 2)
|
||||
backgroundColor = lineModel?.backgroundColor?.uiColor ?? .black
|
||||
case .heavy:
|
||||
heightConstraint?.constant = 4
|
||||
backgroundColor = .black
|
||||
updateLineConstraints(constant: 4)
|
||||
backgroundColor = lineModel?.backgroundColor?.uiColor ?? .black
|
||||
case .none:
|
||||
heightConstraint?.constant = 0
|
||||
updateLineConstraints(constant: 0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,15 +64,17 @@ import UIKit
|
||||
super.setupView()
|
||||
heightConstraint = heightAnchor.constraint(equalToConstant: 1)
|
||||
heightConstraint?.isActive = true
|
||||
widthConstraint = widthAnchor.constraint(equalToConstant: 1)
|
||||
widthConstraint?.isActive = false
|
||||
setStyle(.standard)
|
||||
}
|
||||
|
||||
// MARK: - MoleculeViewProtocol
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
if let lineModel = model as? LineModel {
|
||||
setStyle(lineModel.type)
|
||||
}
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
|
||||
@ -48,8 +48,13 @@ import UIKit
|
||||
// public var color: Color?
|
||||
public var backgroundColor: Color?
|
||||
|
||||
// Use this to show vertical line
|
||||
// Default is false
|
||||
public var useVerticalLine: Bool?
|
||||
|
||||
public init(type: Style) {
|
||||
self.type = type
|
||||
self.useVerticalLine = false
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
@ -58,6 +63,7 @@ import UIKit
|
||||
case backgroundColor
|
||||
case color
|
||||
case frequency
|
||||
case useVerticalLine
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
@ -69,6 +75,7 @@ import UIKit
|
||||
self.frequency = frequency
|
||||
}
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
useVerticalLine = try typeContainer.decodeIfPresent(Bool.self, forKey: .useVerticalLine)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@ -77,5 +84,6 @@ import UIKit
|
||||
try container.encode(type, forKey: .type)
|
||||
try container.encodeIfPresent(frequency, forKey: .frequency)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(useVerticalLine, forKey: .useVerticalLine)
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +51,9 @@ import Foundation
|
||||
try? ModelRegistry.register(LabelAttributeStrikeThroughModel.self)
|
||||
try? ModelRegistry.register(LabelAttributeActionModel.self)
|
||||
|
||||
// TextView
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: TextView.self, viewModelClass: TextViewModel.self)
|
||||
|
||||
// Buttons
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: TwoButtonView.self, viewModelClass: TwoButtonViewModel.self)
|
||||
@ -89,6 +92,7 @@ import Foundation
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: Tabs.self, viewModelClass: TabsModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: TwoLinkView.self, viewModelClass: TwoLinkViewModel.self)
|
||||
|
||||
// Vertical Combination Molecules
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self)
|
||||
@ -126,6 +130,7 @@ import Foundation
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: FooterView.self, viewModelClass: FooterModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: Scroller.self, viewModelClass: ScrollerModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ModuleMolecule.self, viewModelClass: ModuleMoleculeModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: BGImageMolecule.self, viewModelClass: BGImageMoleculeModel.self)
|
||||
|
||||
// Other Molecules
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: DoughnutChartView.self, viewModelClass: DoughnutChartModel.self)
|
||||
@ -173,12 +178,11 @@ import Foundation
|
||||
|
||||
// Device Items
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonMedium.self, viewModelClass: ListDeviceComplexButtonMediumModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonSmall.self, viewModelClass: ListDeviceComplexButtonSmallModel.self)
|
||||
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkSmall.self, viewModelClass: ListDeviceComplexLinkSmallModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkMedium.self, viewModelClass: ListDeviceComplexLinkMediumModel.self)
|
||||
|
||||
// TODO: Need View
|
||||
try? ModelRegistry.register(TabsModel.self)
|
||||
|
||||
// Helper models
|
||||
try? ModelRegistry.register(RuleRequiredModel.self)
|
||||
try? ModelRegistry.register(RuleAnyRequiredModel.self)
|
||||
|
||||
@ -21,15 +21,16 @@ import Foundation
|
||||
// MARK: - Initializers
|
||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
rightImageView.addSizeConstraintsForAspectRatio = true
|
||||
rightImageView.imageView.contentMode = .scaleAspectFit
|
||||
rightImageView.heightAnchor.constraint(equalToConstant: 116.0).isActive = true
|
||||
rightImageView.widthAnchor.constraint(equalToConstant: 116.0).isActive = true
|
||||
verticalStack = Stack<StackModel>.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)),
|
||||
(view: headline, model: StackItemModel(horizontalAlignment: .leading)),
|
||||
(view: body, model: StackItemModel(horizontalAlignment: .leading)),
|
||||
(view: body2, model: StackItemModel(horizontalAlignment: .leading)),
|
||||
(view: button, model: StackItemModel(spacing:16, horizontalAlignment: .leading))],
|
||||
(view: button, model: StackItemModel(spacing: 16, horizontalAlignment: .leading))],
|
||||
axis: .vertical, spacing: 0)
|
||||
stack = Stack<StackModel>.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading, verticalAlignment: .leading)),
|
||||
stack = Stack<StackModel>.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading, verticalAlignment: .leading)),
|
||||
(view: rightImageView, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .center))],
|
||||
axis: .horizontal)
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
//
|
||||
// ListDeviceComplexButtonSmall.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Dhamodaram Nandi on 24/04/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@objcMembers open class ListDeviceComplexButtonSmall: TableViewCell {
|
||||
|
||||
public var verticalStack: Stack<StackModel>
|
||||
public let eyebrow = Label.createLabelRegularMicro(true)
|
||||
public let headline = Label.createLabelBoldTitleMedium(true)
|
||||
public let body = Label.createLabelRegularBodySmall(true)
|
||||
public let body2 = Label.createLabelRegularBodySmall(true)
|
||||
public let button = PillButton(frame: .zero)
|
||||
public let rightImageView = MFLoadImageView()
|
||||
public var stack: Stack<StackModel>
|
||||
|
||||
// MARK: - Initializers
|
||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
rightImageView.addSizeConstraintsForAspectRatio = true
|
||||
rightImageView.imageView.contentMode = .scaleAspectFit
|
||||
rightImageView.heightAnchor.constraint(equalToConstant: 71.0).isActive = true
|
||||
rightImageView.widthAnchor.constraint(equalToConstant: 71.0).isActive = true
|
||||
verticalStack = Stack<StackModel>.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)),
|
||||
(view: headline, model: StackItemModel(horizontalAlignment: .leading)),
|
||||
(view: body, model: StackItemModel(horizontalAlignment: .leading)),
|
||||
(view: body2, model: StackItemModel(horizontalAlignment: .leading)),
|
||||
(view: button, model: StackItemModel(spacing: 16, horizontalAlignment: .leading))],
|
||||
axis: .vertical, spacing: 0)
|
||||
stack = Stack<StackModel>.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading, verticalAlignment: .leading)),
|
||||
(view: rightImageView, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .center))],
|
||||
axis: .horizontal)
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
}
|
||||
|
||||
public required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
// MARK: - MFViewProtocol
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
addMolecule(stack)
|
||||
stack.restack()
|
||||
verticalStack.restack()
|
||||
}
|
||||
|
||||
// MARK: - ModelMoleculeViewProtocol
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
guard let model = model as? ListDeviceComplexButtonSmallModel else { return }
|
||||
verticalStack.updateContainedMolecules(with: [model.eyebrow,
|
||||
model.headline,
|
||||
model.body,
|
||||
model.body2,
|
||||
model.button],
|
||||
delegateObject, additionalData)
|
||||
rightImageView.set(with: model.image, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
return 120
|
||||
}
|
||||
|
||||
public func setDefault() {
|
||||
eyebrow.styleRegularMicro(true)
|
||||
headline.styleBoldTitleMedium(true)
|
||||
body.styleRegularBodySmall(true)
|
||||
body2.styleRegularBodySmall(true)
|
||||
eyebrow.textColor = .mvmCoolGray6
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
setDefault()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
//
|
||||
// ListDeviceComplexButtonSmallModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Dhamodaram Nandi on 24/04/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
public class ListDeviceComplexButtonSmallModel: ListItemModel, MoleculeModelProtocol {
|
||||
public static var identifier: String = "listDvcBtnS"
|
||||
public var eyebrow: LabelModel?
|
||||
public var headline: LabelModel?
|
||||
public var body: LabelModel?
|
||||
public var body2: LabelModel?
|
||||
public var button: ButtonModel
|
||||
public var image: ImageViewModel
|
||||
|
||||
public init(eyebrow: LabelModel, headline:LabelModel, body: LabelModel, body2: LabelModel, button: ButtonModel, image: ImageViewModel) {
|
||||
self.eyebrow = eyebrow
|
||||
self.headline = headline
|
||||
self.body = body
|
||||
self.body2 = body2
|
||||
self.button = button
|
||||
self.image = image
|
||||
super.init()
|
||||
}
|
||||
|
||||
/// Defaults to set
|
||||
override public func setDefaults() {
|
||||
super.setDefaults()
|
||||
button.size = .tiny
|
||||
button.style = .secondary
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case eyebrow
|
||||
case headline
|
||||
case body
|
||||
case body2
|
||||
case button
|
||||
case image
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow)
|
||||
headline = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .headline)
|
||||
body = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body)
|
||||
body2 = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body2)
|
||||
button = try typeContainer.decode(ButtonModel.self, forKey: .button)
|
||||
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeIfPresent(eyebrow, forKey: .eyebrow)
|
||||
try container.encodeIfPresent(headline, forKey: .headline)
|
||||
try container.encodeIfPresent(body, forKey: .body)
|
||||
try container.encodeIfPresent(body2, forKey: .body2)
|
||||
try container.encode(button, forKey: .button)
|
||||
try container.encode(image, forKey: .image)
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,7 @@ import Foundation
|
||||
public let headline = Label.createLabelBoldTitleMedium(true)
|
||||
public let body = Label.createLabelRegularBodySmall(true)
|
||||
public let body2 = Label.createLabelRegularBodySmall(true)
|
||||
public let link = Link()
|
||||
public let twoLinkView = TwoLinkView()
|
||||
public let rightImage = MFLoadImageView()
|
||||
let verticalStack: Stack<StackModel>
|
||||
public let stack: Stack<StackModel>
|
||||
@ -26,11 +26,14 @@ import Foundation
|
||||
//------------------------------------------------------
|
||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
rightImage.addSizeConstraintsForAspectRatio = true
|
||||
rightImage.imageView.contentMode = .scaleAspectFit
|
||||
rightImage.heightAnchor.constraint(equalToConstant: 116.0).isActive = true
|
||||
rightImage.widthAnchor.constraint(equalToConstant: 116.0).isActive = true
|
||||
verticalStack = Stack<StackModel>.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)), (view: headline, model: StackItemModel(horizontalAlignment: .leading)), (view: body, model: StackItemModel(horizontalAlignment: .leading)), (view: body2, model: StackItemModel(horizontalAlignment: .leading)), (view: link, model: StackItemModel(spacing: 16, horizontalAlignment: .leading))], axis: .vertical, spacing: 0)
|
||||
verticalStack = Stack<StackModel>.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)), (view: headline, model: StackItemModel(horizontalAlignment: .leading)), (view: body, model: StackItemModel(horizontalAlignment: .leading)), (view: body2, model: StackItemModel(horizontalAlignment: .leading)), (view: twoLinkView, model: StackItemModel(spacing: 16, horizontalAlignment: .leading))], axis: .vertical, spacing: 0)
|
||||
|
||||
stack = Stack<StackModel>.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading)), (view: rightImage, model: StackItemModel(verticalAlignment: .center))], axis: .horizontal)
|
||||
stack = Stack<StackModel>.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading, verticalAlignment: .leading)),
|
||||
(view: rightImage, model: StackItemModel(verticalAlignment: .center))],
|
||||
axis: .horizontal)
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
}
|
||||
|
||||
@ -54,7 +57,7 @@ import Foundation
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
guard let model = model as? ListDeviceComplexLinkMediumModel else { return }
|
||||
verticalStack.updateContainedMolecules(with: [model.eyebrow, model.headline, model.body, model.body2, model.link], delegateObject, additionalData)
|
||||
verticalStack.updateContainedMolecules(with: [model.eyebrow, model.headline, model.body, model.body2, model.twoLinkView], delegateObject, additionalData)
|
||||
rightImage.set(with: model.image, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
|
||||
@ -13,15 +13,15 @@ public class ListDeviceComplexLinkMediumModel: ListItemModel, MoleculeModelProto
|
||||
public var headline: LabelModel?
|
||||
public var body: LabelModel?
|
||||
public var body2: LabelModel?
|
||||
public var link: LinkModel
|
||||
public var twoLinkView: TwoLinkViewModel
|
||||
public var image: ImageViewModel
|
||||
|
||||
public init(eyebrow: LabelModel, headline: LabelModel, body: LabelModel, body2: LabelModel, link: LinkModel, image: ImageViewModel) {
|
||||
public init(eyebrow: LabelModel, headline: LabelModel, body: LabelModel, body2: LabelModel, twoLinkView: TwoLinkViewModel, image: ImageViewModel) {
|
||||
self.eyebrow = eyebrow
|
||||
self.headline = headline
|
||||
self.body = body
|
||||
self.body2 = body2
|
||||
self.link = link
|
||||
self.twoLinkView = twoLinkView
|
||||
self.image = image
|
||||
super.init()
|
||||
}
|
||||
@ -32,7 +32,7 @@ public class ListDeviceComplexLinkMediumModel: ListItemModel, MoleculeModelProto
|
||||
case headline
|
||||
case body
|
||||
case body2
|
||||
case link
|
||||
case twoLinkView
|
||||
case image
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ public class ListDeviceComplexLinkMediumModel: ListItemModel, MoleculeModelProto
|
||||
headline = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .headline)
|
||||
body = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body)
|
||||
body2 = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body2)
|
||||
link = try typeContainer.decode(LinkModel.self, forKey: .link)
|
||||
twoLinkView = try typeContainer.decode(TwoLinkViewModel.self, forKey: .twoLinkView)
|
||||
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
@ -55,7 +55,7 @@ public class ListDeviceComplexLinkMediumModel: ListItemModel, MoleculeModelProto
|
||||
try container.encodeIfPresent(headline, forKey: .headline)
|
||||
try container.encodeIfPresent(body, forKey: .body)
|
||||
try container.encodeIfPresent(body2, forKey: .body2)
|
||||
try container.encode(link, forKey: .link)
|
||||
try container.encode(twoLinkView, forKey: .twoLinkView)
|
||||
try container.encode(image, forKey: .image)
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ import Foundation
|
||||
public let headline = Label.createLabelBoldTitleMedium(true)
|
||||
public let body = Label.createLabelRegularBodySmall(true)
|
||||
public let body2 = Label.createLabelRegularBodySmall(true)
|
||||
public let link = Link()
|
||||
public let twoLinkView = TwoLinkView()
|
||||
public let rightImage = MFLoadImageView()
|
||||
let verticalStack: Stack<StackModel>
|
||||
public let stack: Stack<StackModel>
|
||||
@ -26,11 +26,14 @@ import Foundation
|
||||
//------------------------------------------------------
|
||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
rightImage.addSizeConstraintsForAspectRatio = true
|
||||
rightImage.imageView.contentMode = .scaleAspectFit
|
||||
rightImage.heightAnchor.constraint(equalToConstant: 71.0).isActive = true
|
||||
rightImage.widthAnchor.constraint(equalToConstant: 71.0).isActive = true
|
||||
verticalStack = Stack<StackModel>.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)), (view: headline, model: StackItemModel(horizontalAlignment: .leading)), (view: body, model: StackItemModel(horizontalAlignment: .leading)), (view: body2, model: StackItemModel(horizontalAlignment: .leading)), (view: link, model: StackItemModel(spacing: 16, horizontalAlignment: .leading))], axis: .vertical, spacing: 0)
|
||||
verticalStack = Stack<StackModel>.createStack(with: [(view: eyebrow, model: StackItemModel(horizontalAlignment: .leading)), (view: headline, model: StackItemModel(horizontalAlignment: .leading)), (view: body, model: StackItemModel(horizontalAlignment: .leading)), (view: body2, model: StackItemModel(horizontalAlignment: .leading)), (view: twoLinkView, model: StackItemModel(spacing: 16, horizontalAlignment: .leading))], axis: .vertical, spacing: 0)
|
||||
|
||||
stack = Stack<StackModel>.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading)), (view: rightImage, model: StackItemModel(verticalAlignment: .center))], axis: .horizontal)
|
||||
stack = Stack<StackModel>.createStack(with: [(view: verticalStack, model: StackItemModel(horizontalAlignment: .leading, verticalAlignment: .leading)),
|
||||
(view: rightImage, model: StackItemModel(verticalAlignment: .center))],
|
||||
axis: .horizontal)
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
}
|
||||
|
||||
@ -54,7 +57,7 @@ import Foundation
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
guard let model = model as? ListDeviceComplexLinkSmallModel else { return }
|
||||
verticalStack.updateContainedMolecules(with: [model.eyebrow, model.headline, model.body, model.body2, model.link], delegateObject, additionalData)
|
||||
verticalStack.updateContainedMolecules(with: [model.eyebrow, model.headline, model.body, model.body2, model.twoLinkView], delegateObject, additionalData)
|
||||
rightImage.set(with: model.image, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
|
||||
@ -13,15 +13,15 @@ public class ListDeviceComplexLinkSmallModel: ListItemModel, MoleculeModelProtoc
|
||||
public var headline: LabelModel?
|
||||
public var body: LabelModel?
|
||||
public var body2: LabelModel?
|
||||
public var link: LinkModel
|
||||
public var twoLinkView: TwoLinkViewModel
|
||||
public var image: ImageViewModel
|
||||
|
||||
public init(eyebrow: LabelModel, headline: LabelModel, body: LabelModel, body2: LabelModel, link: LinkModel, image: ImageViewModel) {
|
||||
public init(eyebrow: LabelModel, headline: LabelModel, body: LabelModel, body2: LabelModel, twoLinkView: TwoLinkViewModel, image: ImageViewModel) {
|
||||
self.eyebrow = eyebrow
|
||||
self.headline = headline
|
||||
self.body = body
|
||||
self.body2 = body2
|
||||
self.link = link
|
||||
self.twoLinkView = twoLinkView
|
||||
self.image = image
|
||||
super.init()
|
||||
}
|
||||
@ -32,7 +32,7 @@ public class ListDeviceComplexLinkSmallModel: ListItemModel, MoleculeModelProtoc
|
||||
case headline
|
||||
case body
|
||||
case body2
|
||||
case link
|
||||
case twoLinkView
|
||||
case image
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ public class ListDeviceComplexLinkSmallModel: ListItemModel, MoleculeModelProtoc
|
||||
headline = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .headline)
|
||||
body = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body)
|
||||
body2 = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body2)
|
||||
link = try typeContainer.decode(LinkModel.self, forKey: .link)
|
||||
twoLinkView = try typeContainer.decode(TwoLinkViewModel.self, forKey: .twoLinkView)
|
||||
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
@ -55,7 +55,7 @@ public class ListDeviceComplexLinkSmallModel: ListItemModel, MoleculeModelProtoc
|
||||
try container.encodeIfPresent(headline, forKey: .headline)
|
||||
try container.encodeIfPresent(body, forKey: .body)
|
||||
try container.encodeIfPresent(body2, forKey: .body2)
|
||||
try container.encode(link, forKey: .link)
|
||||
try container.encode(twoLinkView, forKey: .twoLinkView)
|
||||
try container.encode(image, forKey: .image)
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,109 @@
|
||||
//
|
||||
// TwoLinkView.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/29/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers open class TwoLinkView: View, MVMCoreUIViewConstrainingProtocol {
|
||||
open var leftLink = Link()
|
||||
open var rightLink = Link()
|
||||
private var stack = UIStackView()
|
||||
|
||||
public init() {
|
||||
super.init(frame: .zero)
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
stack.updateView(size)
|
||||
}
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
|
||||
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(stack)
|
||||
stack.addArrangedSubview(leftLink)
|
||||
stack.addArrangedSubview(rightLink)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
|
||||
stack.axis = .horizontal
|
||||
stack.spacing = 8
|
||||
}
|
||||
|
||||
// MARK: - Stack Manipulation
|
||||
public func showRightLink() {
|
||||
if !stack.arrangedSubviews.contains(rightLink) {
|
||||
stack.addArrangedSubview(rightLink)
|
||||
rightLink.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
public func showLeftLink() {
|
||||
if !stack.arrangedSubviews.contains(leftLink) {
|
||||
stack.insertArrangedSubview(leftLink, at: 0)
|
||||
leftLink.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
public func hideRightLink() {
|
||||
if rightLink.superview != nil {
|
||||
stack.removeArrangedSubview(rightLink)
|
||||
rightLink.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
public func hideLeftLink() {
|
||||
if leftLink.superview != nil {
|
||||
stack.removeArrangedSubview(leftLink)
|
||||
leftLink.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - MoleculeViewProtocol
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
stack.reset()
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIViewConstrainingProtocol
|
||||
open func horizontalAlignment() -> UIStackView.Alignment {
|
||||
return .center
|
||||
}
|
||||
|
||||
// MARK: - MoleculeViewProtocol
|
||||
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 16
|
||||
}
|
||||
|
||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
|
||||
guard let model = model as? TwoLinkViewModel else { return }
|
||||
|
||||
if let model = model.leftLink {
|
||||
showLeftLink()
|
||||
leftLink.set(with: model, delegateObject, additionalData)
|
||||
} else {
|
||||
hideLeftLink()
|
||||
}
|
||||
if let model = model.rightLink {
|
||||
showRightLink()
|
||||
rightLink.set(with: model, delegateObject, additionalData)
|
||||
} else {
|
||||
hideRightLink()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
//
|
||||
// TwoLinkViewModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/29/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public class TwoLinkViewModel: MoleculeModelProtocol {
|
||||
public static var identifier: String = "twoLinkView"
|
||||
public var backgroundColor: Color?
|
||||
public var rightLink: LinkModel?
|
||||
public var leftLink: LinkModel?
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case rightLink
|
||||
case leftLink
|
||||
}
|
||||
|
||||
public init(_ rightLink: LinkModel?, _ leftLink: LinkModel?) {
|
||||
self.rightLink = rightLink
|
||||
self.leftLink = leftLink
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
rightLink = try typeContainer.decodeIfPresent(LinkModel.self, forKey: .rightLink)
|
||||
leftLink = try typeContainer.decodeIfPresent(LinkModel.self, forKey: .leftLink)
|
||||
}
|
||||
|
||||
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(rightLink, forKey: .rightLink)
|
||||
try container.encodeIfPresent(leftLink, forKey: .leftLink)
|
||||
}
|
||||
}
|
||||
@ -45,8 +45,11 @@ import Foundation
|
||||
if useVerticalMargins == nil {
|
||||
useVerticalMargins = true
|
||||
}
|
||||
if style == nil {
|
||||
style = "standard"
|
||||
if topPadding == nil {
|
||||
topPadding = 24
|
||||
}
|
||||
if bottomPadding == nil {
|
||||
bottomPadding = 24
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
//
|
||||
// BGImageMolecule.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/28/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
open class BGImageMolecule: MoleculeContainer {
|
||||
|
||||
let image = MFLoadImageView(pinnedEdges: .all)
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
insertSubview(image, at: 0)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: image)
|
||||
}
|
||||
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
image.setOptional(with: (model as? BGImageMoleculeModel)?.image, delegateObject, additionalData)
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
//
|
||||
// BGImageMoleculeModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/28/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
open class BGImageMoleculeModel: MoleculeContainerModel {
|
||||
public override class var identifier: String {
|
||||
return "bgImageContainer"
|
||||
}
|
||||
public var image: ImageViewModel
|
||||
|
||||
open override func setDefaults() {
|
||||
if useHorizontalMargins == nil {
|
||||
useHorizontalMargins = true
|
||||
}
|
||||
if useVerticalMargins == nil {
|
||||
useVerticalMargins = true
|
||||
}
|
||||
if topPadding == nil {
|
||||
topPadding = PaddingDefaultVerticalSpacing3
|
||||
}
|
||||
if bottomPadding == nil {
|
||||
bottomPadding = PaddingDefaultVerticalSpacing3
|
||||
}
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case image
|
||||
}
|
||||
|
||||
public init(_ image: ImageViewModel, molecule: MoleculeModelProtocol) {
|
||||
self.image = image
|
||||
super.init(with: molecule)
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
image = try typeContainer.decode(ImageViewModel.self, forKey:.image)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(image, forKey: .image)
|
||||
}
|
||||
}
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProtocol, MoleculeModelProtocol {
|
||||
open class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProtocol, MoleculeModelProtocol {
|
||||
public class var identifier: String {
|
||||
return "container"
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
//
|
||||
// ThreeLayerFillMiddleTemplate.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/28/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
@objcMembers open class ThreeLayerFillMiddleTemplate: ThreeLayerTemplate<ThreeLayerFillMiddleTemplateModel> {
|
||||
open override func spaceBetweenMiddleAndBottom() -> CGFloat? {
|
||||
return 0
|
||||
}
|
||||
|
||||
open override func handleNewData() {
|
||||
super.handleNewData()
|
||||
heightConstraint?.isActive = true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
//
|
||||
// ThreeLayerFillMiddleTemplateModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/28/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class ThreeLayerFillMiddleTemplateModel: ThreeLayerPageTemplateModel {
|
||||
public override class var identifier: String {
|
||||
return "threeLayerFillMiddle"
|
||||
}
|
||||
}
|
||||
@ -49,4 +49,8 @@ import UIKit
|
||||
open override func spaceBetweenTopAndMiddle() -> CGFloat? {
|
||||
return 0
|
||||
}
|
||||
|
||||
open override func spaceBetweenMiddleAndBottom() -> CGFloat? {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,6 +148,7 @@ import UIKit
|
||||
preservesSuperviewLayoutMargins = false
|
||||
contentView.insetsLayoutMarginsFromSafeArea = false
|
||||
contentView.preservesSuperviewLayoutMargins = false
|
||||
styleStandard()
|
||||
}
|
||||
|
||||
//TODO: ModelProtocol, Change to model
|
||||
@ -183,6 +184,7 @@ import UIKit
|
||||
|
||||
open func reset() {
|
||||
molecule?.reset()
|
||||
styleStandard()
|
||||
backgroundColor = .white
|
||||
}
|
||||
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
public protocol TextFieldDidDeleteProtocol: class {
|
||||
func textFieldDidDelete()
|
||||
public protocol TextInputDidDeleteProtocol: class {
|
||||
func textInputDidDelete()
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ public protocol TextFieldDidDeleteProtocol: class {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
private var initialSetupPerformed = false
|
||||
|
||||
/// Set to true to hide the blinking textField cursor.
|
||||
@ -27,7 +28,7 @@ public protocol TextFieldDidDeleteProtocol: class {
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well.
|
||||
public weak var didDeleteDelegate: TextFieldDidDeleteProtocol?
|
||||
public weak var didDeleteDelegate: TextInputDidDeleteProtocol?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initialization
|
||||
@ -50,7 +51,7 @@ public protocol TextFieldDidDeleteProtocol: class {
|
||||
public func initialSetup() {
|
||||
|
||||
if !initialSetupPerformed {
|
||||
tintColor = .black
|
||||
tintColor = .mvmBlack
|
||||
initialSetupPerformed = true
|
||||
setupView()
|
||||
}
|
||||
@ -68,7 +69,7 @@ public protocol TextFieldDidDeleteProtocol: class {
|
||||
|
||||
open override func deleteBackward() {
|
||||
super.deleteBackward()
|
||||
didDeleteDelegate?.textFieldDidDelete()
|
||||
didDeleteDelegate?.textInputDidDelete()
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,7 +87,9 @@ extension TextField: MVMCoreViewProtocol {
|
||||
|
||||
/// MARK:- MoleculeViewProtocol
|
||||
extension TextField: MoleculeViewProtocol {
|
||||
open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
|
||||
open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
if let color = model.backgroundColor?.uiColor {
|
||||
backgroundColor = color
|
||||
}
|
||||
|
||||
490
MVMCoreUI/BaseClasses/TextView.swift
Normal file
490
MVMCoreUI/BaseClasses/TextView.swift
Normal file
@ -0,0 +1,490 @@
|
||||
//
|
||||
// TextView.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Kevin Christiano on 4/1/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
@objc open class TextView: UITextView, UITextViewDelegate, MVMCoreViewProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
open var model: MoleculeModelProtocol?
|
||||
|
||||
private var initialSetupPerformed = false
|
||||
|
||||
/// If true then text textView is currently displaying the stored placeholder text as there is not content to display.
|
||||
public var isShowingPlaceholder: Bool = false {
|
||||
didSet { textViewModel?.showsPlaceholder = isShowingPlaceholder }
|
||||
}
|
||||
|
||||
/// Set to true to hide the blinking textField cursor.
|
||||
public var hideBlinkingCaret = false
|
||||
|
||||
public var textViewModel: TextViewModel? {
|
||||
return model as? TextViewModel
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Drawing Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
private(set) var fieldState: FieldState = .original {
|
||||
didSet (oldState) {
|
||||
// Will not update if new state is the same as old.
|
||||
if fieldState != oldState {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.fieldState.setStateUI(for: self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines if the top, left, and right borders should be drawn.
|
||||
private var hideBorders = false
|
||||
|
||||
public var borderStrokeColor: UIColor = .mvmCoolGray3
|
||||
public var bottomStrokeColor: UIColor = .mvmBlack
|
||||
private var borderPath: UIBezierPath = UIBezierPath()
|
||||
private var bottomPath: UIBezierPath = UIBezierPath()
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Property Observers
|
||||
//--------------------------------------------------
|
||||
|
||||
private var _isEnabled: Bool = true
|
||||
private var _showError: Bool = false
|
||||
private var _isSelected: Bool = false
|
||||
|
||||
public var isEnabled: Bool {
|
||||
get { return _isEnabled }
|
||||
set (enabled) {
|
||||
|
||||
_isEnabled = enabled
|
||||
_isSelected = false
|
||||
_showError = false
|
||||
|
||||
fieldState = enabled ? .original : .disabled
|
||||
}
|
||||
}
|
||||
|
||||
public var showError: Bool {
|
||||
get { return _showError }
|
||||
set (error) {
|
||||
|
||||
_showError = error
|
||||
_isEnabled = true
|
||||
_isSelected = false
|
||||
|
||||
fieldState = error ? .error : .original
|
||||
}
|
||||
}
|
||||
|
||||
public var isSelected: Bool {
|
||||
get { return _isSelected }
|
||||
set (selected) {
|
||||
|
||||
_isSelected = selected
|
||||
_isEnabled = true
|
||||
|
||||
if _showError {
|
||||
fieldState = selected ? .selectedError : .error
|
||||
} else {
|
||||
fieldState = selected ? .selected : .original
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Delegate
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well.
|
||||
public weak var didDeleteDelegate: TextInputDidDeleteProtocol?
|
||||
|
||||
/// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well.
|
||||
private weak var proprietorTextDelegate: UITextViewDelegate?
|
||||
|
||||
/// If you're using a ViewController, you must set this to it.
|
||||
public weak var uiTextViewDelegate: UITextViewDelegate? {
|
||||
get { return delegate }
|
||||
set {
|
||||
delegate = self
|
||||
proprietorTextDelegate = newValue
|
||||
}
|
||||
}
|
||||
|
||||
var delegateObject: MVMCoreUIDelegateObject?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Constraint
|
||||
//--------------------------------------------------
|
||||
|
||||
public var heightConstraint: NSLayoutConstraint?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initialization
|
||||
//--------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect, textContainer: NSTextContainer?) {
|
||||
super.init(frame: .zero, textContainer: nil)
|
||||
initialSetup()
|
||||
}
|
||||
|
||||
public convenience init() {
|
||||
self.init(frame: .zero, textContainer: nil)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
initialSetup()
|
||||
}
|
||||
|
||||
convenience init(delegate: UITextViewDelegate) {
|
||||
self.init(frame: .zero, textContainer: nil)
|
||||
self.delegate = delegate
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
public func initialSetup() {
|
||||
|
||||
if !initialSetupPerformed {
|
||||
tintColor = .mvmBlack
|
||||
initialSetupPerformed = true
|
||||
setupView()
|
||||
}
|
||||
}
|
||||
|
||||
open func updateView(_ size: CGFloat) {
|
||||
|
||||
setNeedsDisplay()
|
||||
}
|
||||
|
||||
/// Will be called only once.
|
||||
open func setupView() {
|
||||
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
initialConfiguration()
|
||||
}
|
||||
|
||||
public func initialConfiguration() {
|
||||
|
||||
insetsLayoutMarginsFromSafeArea = false
|
||||
showsVerticalScrollIndicator = false
|
||||
showsHorizontalScrollIndicator = false
|
||||
isSecureTextEntry = false
|
||||
textContainerInset = UIEdgeInsets(top: Padding.Three, left: Padding.Three, bottom: Padding.Three, right: Padding.Three)
|
||||
backgroundColor = .mvmWhite
|
||||
clipsToBounds = true
|
||||
smartQuotesType = .no
|
||||
smartDashesType = .no
|
||||
smartInsertDeleteType = .no
|
||||
inputAccessoryView = nil
|
||||
font = textViewModel?.fontStyle.getFont()
|
||||
isEditable = true
|
||||
isOpaque = false
|
||||
}
|
||||
|
||||
open func reset() {
|
||||
|
||||
text = ""
|
||||
inputAccessoryView?.removeFromSuperview()
|
||||
inputAccessoryView = nil
|
||||
initialConfiguration()
|
||||
}
|
||||
|
||||
open override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
setNeedsDisplay()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Draw
|
||||
//--------------------------------------------------
|
||||
|
||||
/// This handles the top, left, and right border lines.
|
||||
open override func draw(_ rect: CGRect) {
|
||||
super.draw(rect)
|
||||
|
||||
borderPath.removeAllPoints()
|
||||
bottomPath.removeAllPoints()
|
||||
|
||||
if !hideBorders {
|
||||
// Brings the other half of the line inside the view to prevent line cropping.
|
||||
let origin = bounds.origin
|
||||
let size = frame.size
|
||||
let insetLean: CGFloat = 0.5
|
||||
borderPath.lineWidth = 1
|
||||
|
||||
// Drawing begins and ends from the bottom left.
|
||||
borderPath.move(to: CGPoint(x: origin.x + insetLean, y: origin.y + size.height))
|
||||
borderPath.addLine(to: CGPoint(x: origin.x + insetLean, y: origin.y + insetLean))
|
||||
borderPath.addLine(to: CGPoint(x: origin.x + size.width - insetLean, y: origin.y + insetLean))
|
||||
borderPath.addLine(to: CGPoint(x: origin.x + size.width - insetLean, y: origin.y + size.height))
|
||||
|
||||
borderStrokeColor.setStroke()
|
||||
borderPath.stroke()
|
||||
|
||||
let lineWidth: CGFloat = showError || isSelected ? 4 : 1
|
||||
bottomPath.lineWidth = lineWidth
|
||||
bottomPath.move(to: CGPoint(x: origin.x + size.width, y: origin.y + size.height - (lineWidth / 2)))
|
||||
bottomPath.addLine(to: CGPoint(x: origin.x, y: origin.y + size.height - (lineWidth / 2)))
|
||||
|
||||
bottomStrokeColor.setStroke()
|
||||
bottomPath.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Draw States
|
||||
//--------------------------------------------------
|
||||
|
||||
public enum FieldState {
|
||||
case original
|
||||
case error
|
||||
case selectedError
|
||||
case selected
|
||||
case disabled
|
||||
|
||||
public func setStateUI(for inputField: TextView) {
|
||||
|
||||
switch self {
|
||||
case .original:
|
||||
inputField.originalUI()
|
||||
|
||||
case .error:
|
||||
inputField.errorUI()
|
||||
|
||||
case .selectedError:
|
||||
inputField.selectedErrorUI()
|
||||
|
||||
case .selected:
|
||||
inputField.selectedUI()
|
||||
|
||||
case .disabled:
|
||||
inputField.disabledUI()
|
||||
}
|
||||
|
||||
inputField.setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
open func originalUI() {
|
||||
|
||||
isEditable = textViewModel?.editable ?? true
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = textViewModel?.hideBorders ?? false
|
||||
borderStrokeColor = .mvmCoolGray3
|
||||
bottomStrokeColor = .mvmBlack
|
||||
textColor = isShowingPlaceholder ? textViewModel?.placeholderTextColor.uiColor : textViewModel?.enabledTextColor.uiColor
|
||||
}
|
||||
|
||||
open func errorUI() {
|
||||
|
||||
isEditable = textViewModel?.editable ?? true
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = textViewModel?.hideBorders ?? false
|
||||
borderStrokeColor = .mvmOrange
|
||||
bottomStrokeColor = .mvmOrange
|
||||
textColor = textViewModel?.enabledTextColor.uiColor
|
||||
}
|
||||
|
||||
open func selectedErrorUI() {
|
||||
|
||||
isEditable = textViewModel?.editable ?? true
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = textViewModel?.hideBorders ?? false
|
||||
borderStrokeColor = .mvmBlack
|
||||
bottomStrokeColor = .mvmOrange
|
||||
textColor = textViewModel?.enabledTextColor.uiColor
|
||||
}
|
||||
|
||||
open func selectedUI() {
|
||||
|
||||
isEditable = textViewModel?.editable ?? true
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = textViewModel?.hideBorders ?? false
|
||||
borderStrokeColor = .mvmBlack
|
||||
bottomStrokeColor = .mvmBlack
|
||||
textColor = textViewModel?.enabledTextColor.uiColor
|
||||
}
|
||||
|
||||
open func disabledUI() {
|
||||
|
||||
isEditable = textViewModel?.editable ?? false
|
||||
isUserInteractionEnabled = false
|
||||
hideBorders = textViewModel?.hideBorders ?? false
|
||||
borderStrokeColor = .mvmCoolGray3
|
||||
bottomStrokeColor = .mvmCoolGray3
|
||||
textColor = textViewModel?.disabledTextColor.uiColor
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Alters the blinking caret line as per design standards.
|
||||
open override func caretRect(for position: UITextPosition) -> CGRect {
|
||||
|
||||
if hideBlinkingCaret {
|
||||
return .zero
|
||||
}
|
||||
|
||||
let caretRect = super.caretRect(for: position)
|
||||
return CGRect(origin: caretRect.origin, size: CGSize(width: 1, height: caretRect.height))
|
||||
}
|
||||
|
||||
open override func deleteBackward() {
|
||||
super.deleteBackward()
|
||||
didDeleteDelegate?.textInputDidDelete()
|
||||
}
|
||||
|
||||
public func setTextAppearance() {
|
||||
|
||||
if isShowingPlaceholder {
|
||||
setTextContentTraits()
|
||||
}
|
||||
}
|
||||
|
||||
public func setPlaceholderIfAvailable() {
|
||||
|
||||
if let placeholder = textViewModel?.placeholder, !placeholder.isEmpty && text.isEmpty {
|
||||
setPlaceholderContentTraits()
|
||||
}
|
||||
}
|
||||
|
||||
public func setTextContentTraits() {
|
||||
|
||||
isShowingPlaceholder = false
|
||||
text = ""
|
||||
font = textViewModel?.fontStyle.getFont()
|
||||
textColor = textViewModel?.enabledTextColor.uiColor
|
||||
}
|
||||
|
||||
public func setPlaceholderContentTraits() {
|
||||
|
||||
isShowingPlaceholder = true
|
||||
textColor = textViewModel?.placeholderTextColor.uiColor
|
||||
font = textViewModel?.placeholderFontStyle.getFont()
|
||||
text = textViewModel?.placeholder
|
||||
}
|
||||
|
||||
@objc func dismissFieldInput(_ sender: TextView) {
|
||||
|
||||
resignFirstResponder()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - UITextViewDelegate
|
||||
//--------------------------------------------------
|
||||
|
||||
@objc public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
|
||||
|
||||
return proprietorTextDelegate?.textViewShouldBeginEditing?(textView) ?? true
|
||||
}
|
||||
|
||||
@objc public func textViewDidBeginEditing(_ textView: UITextView) {
|
||||
|
||||
setTextAppearance()
|
||||
isSelected = true
|
||||
proprietorTextDelegate?.textViewDidBeginEditing?(textView)
|
||||
}
|
||||
|
||||
@objc public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
|
||||
|
||||
return proprietorTextDelegate?.textView?(textView, shouldChangeTextIn: range, replacementText: text) ?? true
|
||||
}
|
||||
|
||||
@objc public func textViewDidChange(_ textView: UITextView) {
|
||||
|
||||
textViewModel?.text = textView.text
|
||||
proprietorTextDelegate?.textViewDidChange?(textView)
|
||||
}
|
||||
|
||||
@objc public func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
|
||||
|
||||
return proprietorTextDelegate?.textViewShouldEndEditing?(textView) ?? true
|
||||
}
|
||||
|
||||
@objc public func textViewDidEndEditing(_ textView: UITextView) {
|
||||
|
||||
setPlaceholderIfAvailable()
|
||||
isSelected = false
|
||||
proprietorTextDelegate?.textViewDidEndEditing?(textView)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK:- MoleculeViewProtocol
|
||||
extension TextView: MoleculeViewProtocol {
|
||||
|
||||
open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
self.model = model
|
||||
self.delegateObject = delegateObject
|
||||
|
||||
if let color = model.backgroundColor?.uiColor {
|
||||
backgroundColor = color
|
||||
}
|
||||
|
||||
guard let model = model as? TextViewModel else { return }
|
||||
|
||||
heightConstraint?.isActive = false
|
||||
if let height = model.height {
|
||||
heightConstraint = heightAnchor.constraint(equalToConstant: height)
|
||||
heightConstraint?.isActive = true
|
||||
}
|
||||
|
||||
isEditable = model.editable
|
||||
textAlignment = model.textAlignment
|
||||
textColor = model.enabledTextColor.uiColor
|
||||
hideBorders = model.hideBorders
|
||||
text = model.text
|
||||
uiTextViewDelegate = delegateObject?.uiTextViewDelegate
|
||||
|
||||
if let accessibilityText = model.accessibilityText {
|
||||
accessibilityLabel = accessibilityText
|
||||
}
|
||||
|
||||
switch model.type {
|
||||
case .secure, .password:
|
||||
isSecureTextEntry = true
|
||||
case .number:
|
||||
keyboardType = .numberPad
|
||||
case .email:
|
||||
keyboardType = .emailAddress
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
font = model.fontStyle.getFont()
|
||||
setPlaceholderIfAvailable()
|
||||
|
||||
if isEditable {
|
||||
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
|
||||
let observingDelegate = delegateObject?.uiTextViewDelegate ?? self
|
||||
inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate,
|
||||
action: #selector(dismissFieldInput))
|
||||
|
||||
if (model.selected ?? false) && !model.wasInitiallySelected {
|
||||
model.wasInitiallySelected = true
|
||||
DispatchQueue.main.async {
|
||||
self.becomeFirstResponder()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !model.enabled {
|
||||
isEnabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
95
MVMCoreUI/BaseClasses/TextViewModel.swift
Normal file
95
MVMCoreUI/BaseClasses/TextViewModel.swift
Normal file
@ -0,0 +1,95 @@
|
||||
//
|
||||
// TextViewModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Kevin Christiano on 4/2/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
open class TextViewModel: TextEntryFieldModel {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public override class var identifier: String {
|
||||
return "textView"
|
||||
}
|
||||
|
||||
public var accessibilityText: String?
|
||||
public var fontStyle: Styler.Font = Styler.Font.RegularBodySmall
|
||||
public var textAlignment: NSTextAlignment = .left
|
||||
public var height: CGFloat?
|
||||
public var placeholderTextColor: Color = Color(uiColor: .mvmCoolGray3)
|
||||
public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro
|
||||
public var showsPlaceholder: Bool = false
|
||||
public var hideBorders: Bool = false
|
||||
public var editable: Bool = true
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case text
|
||||
case accessibilityText
|
||||
case fontStyle
|
||||
case textAlignment
|
||||
case height
|
||||
case hideBorders
|
||||
case placeholderFontStyle
|
||||
case placeholderTextColor
|
||||
case editable
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
try super.init(from: decoder)
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
if let placeholderFontStyle = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .placeholderFontStyle) {
|
||||
self.placeholderFontStyle = placeholderFontStyle
|
||||
}
|
||||
|
||||
if let placeholderTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .placeholderTextColor) {
|
||||
self.placeholderTextColor = placeholderTextColor
|
||||
}
|
||||
|
||||
if let textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment) {
|
||||
self.textAlignment = textAlignment
|
||||
}
|
||||
|
||||
if let hideBorders = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideBorders) {
|
||||
self.hideBorders = hideBorders
|
||||
}
|
||||
|
||||
if let editable = try typeContainer.decodeIfPresent(Bool.self, forKey: .editable) {
|
||||
self.editable = editable
|
||||
}
|
||||
|
||||
if let fontStyle = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .fontStyle) {
|
||||
self.fontStyle = fontStyle
|
||||
}
|
||||
|
||||
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||
height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height)
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||
try container.encodeIfPresent(height, forKey: .height)
|
||||
try container.encode(fontStyle, forKey: .fontStyle)
|
||||
try container.encode(hideBorders, forKey: .hideBorders)
|
||||
try container.encode(text, forKey: .text)
|
||||
try container.encode(placeholderFontStyle, forKey: .placeholderFontStyle)
|
||||
try container.encode(placeholderTextColor, forKey: .placeholderTextColor)
|
||||
try container.encode(textAlignment, forKey: .textAlignment)
|
||||
try container.encode(editable, forKey: .editable)
|
||||
}
|
||||
}
|
||||
@ -8,10 +8,13 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
open class MVMCoreUIDelegateObject: DelegateObject {
|
||||
|
||||
public weak var formHolderDelegate: FormHolderProtocol?
|
||||
public weak var buttonDelegate: ButtonDelegateProtocol?
|
||||
public weak var uiTextFieldDelegate: UITextFieldDelegate?
|
||||
public weak var uiTextViewDelegate: UITextViewDelegate?
|
||||
public weak var observingTextFieldDelegate: ObservingTextFieldDelegate?
|
||||
public weak var moleculeDelegate: MoleculeDelegateProtocol?
|
||||
|
||||
@ -20,6 +23,7 @@ open class MVMCoreUIDelegateObject: DelegateObject {
|
||||
formHolderDelegate = delegate as? FormHolderProtocol
|
||||
buttonDelegate = delegate as? ButtonDelegateProtocol
|
||||
uiTextFieldDelegate = delegate as? UITextFieldDelegate
|
||||
uiTextViewDelegate = delegate as? UITextViewDelegate
|
||||
observingTextFieldDelegate = delegate as? ObservingTextFieldDelegate
|
||||
moleculeDelegate = delegate as? MoleculeDelegateProtocol
|
||||
}
|
||||
@ -28,4 +32,3 @@ open class MVMCoreUIDelegateObject: DelegateObject {
|
||||
return controller?.delegateObject?() as? MVMCoreUIDelegateObject
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@ public extension MVMCoreUIViewControllerMappingObject {
|
||||
|
||||
register(template: ThreeLayerTemplate.self)
|
||||
register(template: ThreeLayerCenterTemplate.self)
|
||||
register(template: ThreeLayerFillMiddleTemplate.self)
|
||||
|
||||
register(template: CollectionTemplate.self)
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ open class Styler {
|
||||
}
|
||||
|
||||
/// Returns the font based on the declared enum case.
|
||||
public func getFont(_ genericScaling: Bool = true) -> UIFont? {
|
||||
public func getFont(_ genericScaling: Bool = true) -> UIFont {
|
||||
|
||||
let size = genericScaling ? sizeFontGeneric(forCurrentDevice: pointSize()) : pointSize()
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user