Merge branch 'develop' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui into feature/three_column_plan_data_list
# Conflicts: # MVMCoreUI.xcodeproj/project.pbxproj
This commit is contained in:
commit
bc1cc9b1d2
@ -95,8 +95,6 @@
|
|||||||
0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; };
|
0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; };
|
||||||
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; };
|
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; };
|
||||||
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; };
|
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; };
|
||||||
52DD6C6B23E97B040011ECB2 /* ThreeColumnPlanDataDividerListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DD6C6A23E97B040011ECB2 /* ThreeColumnPlanDataDividerListModel.swift */; };
|
|
||||||
52DD6C6D23E97B5E0011ECB2 /* ThreeColumnPlanDataDividerList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DD6C6C23E97B5E0011ECB2 /* ThreeColumnPlanDataDividerList.swift */; };
|
|
||||||
9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; };
|
9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; };
|
||||||
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; };
|
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; };
|
||||||
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; };
|
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; };
|
||||||
@ -108,6 +106,10 @@
|
|||||||
9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; };
|
9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; };
|
||||||
946EE1BA237B66D80036751F /* MoleculeModelHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1B9237B66D80036751F /* MoleculeModelHelper.swift */; };
|
946EE1BA237B66D80036751F /* MoleculeModelHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1B9237B66D80036751F /* MoleculeModelHelper.swift */; };
|
||||||
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; };
|
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; };
|
||||||
|
94AF4A3E23E9D13900676048 /* MFCaretButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 94AF4A3C23E9D13900676048 /* MFCaretButton.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 94AF4A3D23E9D13900676048 /* MFCaretButton.m */; };
|
||||||
|
94AF4A4223E9D19E00676048 /* MFCaretView.h in Headers */ = {isa = PBXBuildFile; fileRef = 94AF4A4023E9D19E00676048 /* MFCaretView.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */ = {isa = PBXBuildFile; fileRef = 94AF4A4123E9D19E00676048 /* MFCaretView.m */; };
|
||||||
94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9832386F3F80006CF46 /* LabelAttributeModel.swift */; };
|
94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9832386F3F80006CF46 /* LabelAttributeModel.swift */; };
|
||||||
94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A023872BCC0006CF46 /* LabelAttributeUnderlineModel.swift */; };
|
94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A023872BCC0006CF46 /* LabelAttributeUnderlineModel.swift */; };
|
||||||
94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A223872C110006CF46 /* LabelAttributeStrikeThroughModel.swift */; };
|
94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A223872C110006CF46 /* LabelAttributeStrikeThroughModel.swift */; };
|
||||||
@ -325,7 +327,7 @@
|
|||||||
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */; };
|
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */; };
|
||||||
DBC4391822442197001AB423 /* CaretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391622442196001AB423 /* CaretView.swift */; };
|
DBC4391822442197001AB423 /* CaretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391622442196001AB423 /* CaretView.swift */; };
|
||||||
DBC4391922442197001AB423 /* DashLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391722442197001AB423 /* DashLine.swift */; };
|
DBC4391922442197001AB423 /* DashLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391722442197001AB423 /* DashLine.swift */; };
|
||||||
DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretButton.swift */; };
|
DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretLink.swift */; };
|
||||||
DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */; };
|
DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */; };
|
||||||
DBEFFA04225A829700230692 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB891E822253FA8500022516 /* Label.swift */; };
|
DBEFFA04225A829700230692 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB891E822253FA8500022516 /* Label.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
@ -410,8 +412,6 @@
|
|||||||
0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
|
0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
|
||||||
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = "<group>"; };
|
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = "<group>"; };
|
||||||
31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = "<group>"; };
|
31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = "<group>"; };
|
||||||
52DD6C6A23E97B040011ECB2 /* ThreeColumnPlanDataDividerListModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeColumnPlanDataDividerListModel.swift; sourceTree = "<group>"; };
|
|
||||||
52DD6C6C23E97B5E0011ECB2 /* ThreeColumnPlanDataDividerList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeColumnPlanDataDividerList.swift; sourceTree = "<group>"; };
|
|
||||||
9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = "<group>"; };
|
9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = "<group>"; };
|
||||||
9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = "<group>"; };
|
9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = "<group>"; };
|
||||||
943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = "<group>"; };
|
943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = "<group>"; };
|
||||||
@ -424,6 +424,10 @@
|
|||||||
9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = "<group>"; };
|
9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = "<group>"; };
|
||||||
946EE1B9237B66D80036751F /* MoleculeModelHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeModelHelper.swift; sourceTree = "<group>"; };
|
946EE1B9237B66D80036751F /* MoleculeModelHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeModelHelper.swift; sourceTree = "<group>"; };
|
||||||
948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = "<group>"; };
|
948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = "<group>"; };
|
||||||
|
94AF4A3C23E9D13900676048 /* MFCaretButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MFCaretButton.h; sourceTree = "<group>"; };
|
||||||
|
94AF4A3D23E9D13900676048 /* MFCaretButton.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MFCaretButton.m; sourceTree = "<group>"; };
|
||||||
|
94AF4A4023E9D19E00676048 /* MFCaretView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MFCaretView.h; sourceTree = "<group>"; };
|
||||||
|
94AF4A4123E9D19E00676048 /* MFCaretView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MFCaretView.m; sourceTree = "<group>"; };
|
||||||
94C2D9832386F3F80006CF46 /* LabelAttributeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeModel.swift; sourceTree = "<group>"; };
|
94C2D9832386F3F80006CF46 /* LabelAttributeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeModel.swift; sourceTree = "<group>"; };
|
||||||
94C2D9A023872BCC0006CF46 /* LabelAttributeUnderlineModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeUnderlineModel.swift; sourceTree = "<group>"; };
|
94C2D9A023872BCC0006CF46 /* LabelAttributeUnderlineModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeUnderlineModel.swift; sourceTree = "<group>"; };
|
||||||
94C2D9A223872C110006CF46 /* LabelAttributeStrikeThroughModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeStrikeThroughModel.swift; sourceTree = "<group>"; };
|
94C2D9A223872C110006CF46 /* LabelAttributeStrikeThroughModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeStrikeThroughModel.swift; sourceTree = "<group>"; };
|
||||||
@ -654,7 +658,7 @@
|
|||||||
DB891E822253FA8500022516 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = "<group>"; };
|
DB891E822253FA8500022516 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = "<group>"; };
|
||||||
DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = "<group>"; };
|
DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = "<group>"; };
|
||||||
DBC4391722442197001AB423 /* DashLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashLine.swift; sourceTree = "<group>"; };
|
DBC4391722442197001AB423 /* DashLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashLine.swift; sourceTree = "<group>"; };
|
||||||
DBC4391A224421A0001AB423 /* CaretButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretButton.swift; sourceTree = "<group>"; };
|
DBC4391A224421A0001AB423 /* CaretLink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretLink.swift; sourceTree = "<group>"; };
|
||||||
DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelWithInternalButton.swift; sourceTree = "<group>"; };
|
DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelWithInternalButton.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
@ -831,7 +835,13 @@
|
|||||||
D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */,
|
D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */,
|
||||||
D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */,
|
D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */,
|
||||||
D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */,
|
D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */,
|
||||||
|
94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */,
|
||||||
|
94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */,
|
||||||
D282AACA2243C61700C46919 /* ButtonView.swift */,
|
D282AACA2243C61700C46919 /* ButtonView.swift */,
|
||||||
|
94AF4A3C23E9D13900676048 /* MFCaretButton.h */,
|
||||||
|
94AF4A3D23E9D13900676048 /* MFCaretButton.m */,
|
||||||
|
94AF4A4023E9D19E00676048 /* MFCaretView.h */,
|
||||||
|
94AF4A4123E9D19E00676048 /* MFCaretView.m */,
|
||||||
);
|
);
|
||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -875,10 +885,6 @@
|
|||||||
D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */,
|
D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */,
|
||||||
D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */,
|
D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */,
|
||||||
D28A837E23CCA96400DFE4FC /* TabsModel.swift */,
|
D28A837E23CCA96400DFE4FC /* TabsModel.swift */,
|
||||||
94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */,
|
|
||||||
94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */,
|
|
||||||
52DD6C6A23E97B040011ECB2 /* ThreeColumnPlanDataDividerListModel.swift */,
|
|
||||||
52DD6C6C23E97B5E0011ECB2 /* ThreeColumnPlanDataDividerList.swift */,
|
|
||||||
);
|
);
|
||||||
path = HorizontalCombinationViews;
|
path = HorizontalCombinationViews;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1162,7 +1168,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
01F2A03123A4498200D954D8 /* CaretLinkModel.swift */,
|
01F2A03123A4498200D954D8 /* CaretLinkModel.swift */,
|
||||||
DBC4391A224421A0001AB423 /* CaretButton.swift */,
|
DBC4391A224421A0001AB423 /* CaretLink.swift */,
|
||||||
D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */,
|
D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */,
|
||||||
D2E2A99E23E07F8A000B42E6 /* PillButton.swift */,
|
D2E2A99E23E07F8A000B42E6 /* PillButton.swift */,
|
||||||
D28A838823CCCFCB00DFE4FC /* LinkModel.swift */,
|
D28A838823CCCFCB00DFE4FC /* LinkModel.swift */,
|
||||||
@ -1414,6 +1420,7 @@
|
|||||||
D29DF27521E79E81003B2FB9 /* MVMCoreUILoggingHandler.h in Headers */,
|
D29DF27521E79E81003B2FB9 /* MVMCoreUILoggingHandler.h in Headers */,
|
||||||
D29DF28B21E7AC2B003B2FB9 /* ViewConstrainingView.h in Headers */,
|
D29DF28B21E7AC2B003B2FB9 /* ViewConstrainingView.h in Headers */,
|
||||||
D29DF2B321E7B76D003B2FB9 /* MFLoadingSpinner.h in Headers */,
|
D29DF2B321E7B76D003B2FB9 /* MFLoadingSpinner.h in Headers */,
|
||||||
|
94AF4A3E23E9D13900676048 /* MFCaretButton.h in Headers */,
|
||||||
0A21DB8A235E06EF00C160A2 /* MFDigitTextBox.h in Headers */,
|
0A21DB8A235E06EF00C160A2 /* MFDigitTextBox.h in Headers */,
|
||||||
D29DF32521ED0DA2003B2FB9 /* TextButtonView.h in Headers */,
|
D29DF32521ED0DA2003B2FB9 /* TextButtonView.h in Headers */,
|
||||||
0A21DB8C235E06EF00C160A2 /* MFDigitTextField.h in Headers */,
|
0A21DB8C235E06EF00C160A2 /* MFDigitTextField.h in Headers */,
|
||||||
@ -1432,6 +1439,7 @@
|
|||||||
D29DF2CA21E7BFC8003B2FB9 /* MFSizeThreshold.h in Headers */,
|
D29DF2CA21E7BFC8003B2FB9 /* MFSizeThreshold.h in Headers */,
|
||||||
D29DF28021E7AA51003B2FB9 /* MVMCoreUIDetailViewProtocol.h in Headers */,
|
D29DF28021E7AA51003B2FB9 /* MVMCoreUIDetailViewProtocol.h in Headers */,
|
||||||
D29DF2BD21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.h in Headers */,
|
D29DF2BD21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.h in Headers */,
|
||||||
|
94AF4A4223E9D19E00676048 /* MFCaretView.h in Headers */,
|
||||||
D29DF2EE21ECEADF003B2FB9 /* MFFonts.h in Headers */,
|
D29DF2EE21ECEADF003B2FB9 /* MFFonts.h in Headers */,
|
||||||
D29DF12D21E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.h in Headers */,
|
D29DF12D21E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.h in Headers */,
|
||||||
D29770F321F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.h in Headers */,
|
D29770F321F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.h in Headers */,
|
||||||
@ -1642,7 +1650,6 @@
|
|||||||
0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */,
|
0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */,
|
||||||
94FB966323D797DA003D482B /* MFTextButton.m in Sources */,
|
94FB966323D797DA003D482B /* MFTextButton.m in Sources */,
|
||||||
D260105323CEA61600764D80 /* ToggleModel.swift in Sources */,
|
D260105323CEA61600764D80 /* ToggleModel.swift in Sources */,
|
||||||
52DD6C6B23E97B040011ECB2 /* ThreeColumnPlanDataDividerListModel.swift in Sources */,
|
|
||||||
014AA72523C501E2006F3E93 /* ContainerModel.swift in Sources */,
|
014AA72523C501E2006F3E93 /* ContainerModel.swift in Sources */,
|
||||||
0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */,
|
0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */,
|
||||||
D29DF2EF21ECEAE1003B2FB9 /* MFFonts.m in Sources */,
|
D29DF2EF21ECEAE1003B2FB9 /* MFFonts.m in Sources */,
|
||||||
@ -1678,6 +1685,7 @@
|
|||||||
944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */,
|
944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */,
|
||||||
D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */,
|
D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */,
|
||||||
C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */,
|
C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */,
|
||||||
|
94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */,
|
||||||
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
|
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
|
||||||
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */,
|
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */,
|
||||||
D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */,
|
D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */,
|
||||||
@ -1721,13 +1729,13 @@
|
|||||||
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */,
|
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */,
|
||||||
0A21DB83235DFBC500C160A2 /* MdnEntryField.swift in Sources */,
|
0A21DB83235DFBC500C160A2 /* MdnEntryField.swift in Sources */,
|
||||||
D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */,
|
D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */,
|
||||||
52DD6C6D23E97B5E0011ECB2 /* ThreeColumnPlanDataDividerList.swift in Sources */,
|
|
||||||
012A88C6238DA34000FE3DA1 /* ModuleMoleculeModel.swift in Sources */,
|
012A88C6238DA34000FE3DA1 /* ModuleMoleculeModel.swift in Sources */,
|
||||||
94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */,
|
94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */,
|
||||||
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */,
|
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */,
|
||||||
D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */,
|
D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */,
|
||||||
0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */,
|
0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */,
|
||||||
0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */,
|
0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */,
|
||||||
|
94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */,
|
||||||
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */,
|
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */,
|
||||||
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
|
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
|
||||||
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */,
|
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */,
|
||||||
@ -1742,7 +1750,7 @@
|
|||||||
012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */,
|
012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */,
|
||||||
D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */,
|
D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */,
|
||||||
C003506123AA94CD00B6AC29 /* Button.swift in Sources */,
|
C003506123AA94CD00B6AC29 /* Button.swift in Sources */,
|
||||||
DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */,
|
DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */,
|
||||||
0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */,
|
0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */,
|
||||||
0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */,
|
0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */,
|
||||||
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */,
|
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */,
|
||||||
|
|||||||
@ -41,6 +41,12 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol {
|
|||||||
self.action = action
|
self.action = action
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init(secondaryButtonWith title: String, action: ActionModelProtocol) {
|
||||||
|
self.title = title
|
||||||
|
self.action = action
|
||||||
|
style = .secondary
|
||||||
|
}
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case backgroundColor
|
case backgroundColor
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// CaretButton.swift
|
// CaretLink.swift
|
||||||
// MVMCoreUI
|
// MVMCoreUI
|
||||||
//
|
//
|
||||||
// Created by Kolli, Praneeth on 1/5/18.
|
// Created by Kolli, Praneeth on 1/5/18.
|
||||||
@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol, ModelMoleculeViewProtocol {
|
open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol {
|
||||||
|
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
// MARK: - Constants
|
// MARK: - Constants
|
||||||
@ -49,7 +49,9 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI
|
|||||||
didSet { changeCaretColor() }
|
didSet { changeCaretColor() }
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateView(_ size: CGFloat) { }
|
public override func updateView(_ size: CGFloat) {
|
||||||
|
titleLabel?.font = MFStyler.fontB1()
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
@ -61,10 +63,18 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI
|
|||||||
setTitleColor(disabledColor, for: .disabled)
|
setTitleColor(disabledColor, for: .disabled)
|
||||||
|
|
||||||
if let rightCaretView = rightView as? CaretView {
|
if let rightCaretView = rightView as? CaretView {
|
||||||
|
rightCaretView.enabledColor = enabledColor
|
||||||
|
rightCaretView.disabledColor = disabledColor
|
||||||
rightCaretView.isEnabled = isEnabled
|
rightCaretView.isEnabled = isEnabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func createCaretView() -> CaretView {
|
||||||
|
let caret = CaretView()
|
||||||
|
caret.lineWidth = 1.5
|
||||||
|
return caret
|
||||||
|
}
|
||||||
|
|
||||||
private func addCaretImageView() {
|
private func addCaretImageView() {
|
||||||
|
|
||||||
rightView?.removeFromSuperview()
|
rightView?.removeFromSuperview()
|
||||||
@ -75,7 +85,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI
|
|||||||
let edgeInsets: UIEdgeInsets = contentEdgeInsets
|
let edgeInsets: UIEdgeInsets = contentEdgeInsets
|
||||||
contentEdgeInsets = UIEdgeInsets(top: edgeInsets.top, left: edgeInsets.left, bottom: edgeInsets.bottom, right: 4 + width)
|
contentEdgeInsets = UIEdgeInsets(top: edgeInsets.top, left: edgeInsets.left, bottom: edgeInsets.bottom, right: 4 + width)
|
||||||
|
|
||||||
let caretView: UIView = rightView ?? CaretView()
|
let caretView: UIView = rightView ?? createCaretView()
|
||||||
rightView = caretView
|
rightView = caretView
|
||||||
rightView?.translatesAutoresizingMaskIntoConstraints = false
|
rightView?.translatesAutoresizingMaskIntoConstraints = false
|
||||||
addSubview(caretView)
|
addSubview(caretView)
|
||||||
@ -115,33 +125,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI
|
|||||||
setTitleColor(disabledColor, for: .disabled)
|
setTitleColor(disabledColor, for: .disabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
setWithActionMap(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
|
|
||||||
guard let dictionary = json else { return }
|
|
||||||
|
|
||||||
if let title = dictionary.optionalStringForKey(KeyTitle) {
|
|
||||||
setTitle(title, for: .normal)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let disableButtonAsAny = dictionary[KeyDisableButton], let isDisabled = disableButtonAsAny as? Bool {
|
|
||||||
isEnabled = !isDisabled
|
|
||||||
}
|
|
||||||
|
|
||||||
if let backgroundColorHex = dictionary[KeyBackgroundColor] as? String {
|
|
||||||
backgroundColor = UIColor.mfGet(forHex: backgroundColorHex)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let enabledColorHex = dictionary["enabledColor"] as? String {
|
|
||||||
enabledColor = UIColor.mfGet(forHex: enabledColorHex)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let disabledColorHex = dictionary["disabledColor"] as? String {
|
|
||||||
disabledColor = UIColor.mfGet(forHex: disabledColorHex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
|
||||||
guard let caretLinkModel = model as? CaretLinkModel else { return }
|
guard let caretLinkModel = model as? CaretLinkModel else { return }
|
||||||
if let color = caretLinkModel.backgroundColor {
|
if let color = caretLinkModel.backgroundColor {
|
||||||
backgroundColor = color.uiColor
|
backgroundColor = color.uiColor
|
||||||
@ -163,7 +147,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI
|
|||||||
return .leading
|
return .leading
|
||||||
}
|
}
|
||||||
|
|
||||||
public class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
return 10
|
return 10.5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,9 +97,9 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation
|
|||||||
public static func getHeight(for buttonSize: ButtonSize?, size: CGFloat) -> CGFloat {
|
public static func getHeight(for buttonSize: ButtonSize?, size: CGFloat) -> CGFloat {
|
||||||
switch buttonSize {
|
switch buttonSize {
|
||||||
case .tiny:
|
case .tiny:
|
||||||
return MFSizeObject(standardSize: ButtonHeight.tiny.rawValue, standardiPadPortraitSize: 34, iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? 20
|
return MFSizeObject(standardSize: ButtonHeight.tiny.rawValue, standardiPadPortraitSize: 34, iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? ButtonHeight.tiny.rawValue
|
||||||
default:
|
default:
|
||||||
return MFSizeObject(standardSize: ButtonHeight.standard.rawValue, standardiPadPortraitSize: 46, iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? 42
|
return MFSizeObject(standardSize: ButtonHeight.standard.rawValue, standardiPadPortraitSize: 46, iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? ButtonHeight.standard.rawValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation
|
|||||||
case .tiny:
|
case .tiny:
|
||||||
return MFSizeObject(standardSize: 49.0, standardiPadPortraitSize: 90.0, iPadProLandscapeSize: 135.0)?.getValueBased(onSize: size) ?? 49.0
|
return MFSizeObject(standardSize: 49.0, standardiPadPortraitSize: 90.0, iPadProLandscapeSize: 135.0)?.getValueBased(onSize: size) ?? 49.0
|
||||||
default:
|
default:
|
||||||
return MFSizeObject(standardSize: 102.0, standardiPadPortraitSize: 136.0, iPadProLandscapeSize: 153.0)?.getValueBased(onSize: size) ?? 102.0
|
return 151.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import UIKit
|
|||||||
let caret = CaretView()
|
let caret = CaretView()
|
||||||
caret.direction = .down
|
caret.direction = .down
|
||||||
caret.lineWidth = 1.5
|
caret.lineWidth = 1.5
|
||||||
caret.isUserInteractionEnabled = true
|
caret.isUserInteractionEnabled = false
|
||||||
caret.heightAnchor.constraint(equalToConstant: 9).isActive = true
|
caret.heightAnchor.constraint(equalToConstant: 9).isActive = true
|
||||||
caret.widthAnchor.constraint(equalToConstant: 16).isActive = true
|
caret.widthAnchor.constraint(equalToConstant: 16).isActive = true
|
||||||
return caret
|
return caret
|
||||||
|
|||||||
@ -26,6 +26,10 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
|||||||
/// Closure passed here will run upon dismissing the selection picker.
|
/// Closure passed here will run upon dismissing the selection picker.
|
||||||
public var observeDropdownSelection: ((String)->())?
|
public var observeDropdownSelection: ((String)->())?
|
||||||
|
|
||||||
|
public var itemDropdownEntryFieldModel: ItemDropdownEntryFieldModel? {
|
||||||
|
return model as? ItemDropdownEntryFieldModel
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -100,7 +104,7 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
|||||||
setPickerDelegates(delegate: self)
|
setPickerDelegates(delegate: self)
|
||||||
|
|
||||||
if let pickerView = pickerView {
|
if let pickerView = pickerView {
|
||||||
self.pickerView(pickerView, didSelectRow: 0, inComponent: 0)
|
self.pickerView(pickerView, didSelectRow: model.selectedIndex, inComponent: 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,6 +131,7 @@ extension ItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource {
|
|||||||
|
|
||||||
observeDropdownChange?(text ?? "", pickerData[row])
|
observeDropdownChange?(text ?? "", pickerData[row])
|
||||||
text = pickerData[row]
|
text = pickerData[row]
|
||||||
|
itemDropdownEntryFieldModel?.selectedIndex = row
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public var options: [String] = []
|
public var options: [String] = []
|
||||||
|
public var selectedIndex: Int = 0
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
@ -24,6 +25,7 @@
|
|||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case options
|
case options
|
||||||
|
case selectedIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -34,6 +36,7 @@
|
|||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
options = try typeContainer.decode([String].self, forKey: .options)
|
options = try typeContainer.decode([String].self, forKey: .options)
|
||||||
|
selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) ?? 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
@ -41,5 +44,6 @@
|
|||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
try container.encode(options, forKey: .options)
|
try container.encode(options, forKey: .options)
|
||||||
|
try container.encode(options, forKey: .selectedIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
|
||||||
@objc public protocol ObservingTextFieldDelegate: NSObjectProtocol {
|
@objc public protocol ObservingTextFieldDelegate {
|
||||||
/// Called when the entered text becomes valid based on the validation block
|
/// Called when the entered text becomes valid based on the validation block
|
||||||
@objc optional func isValid(textfield: TextEntryField?)
|
@objc optional func isValid(textfield: TextEntryField?)
|
||||||
/// Called when the entered text becomes invalid based on the validation block
|
/// Called when the entered text becomes invalid based on the validation block
|
||||||
@ -25,7 +25,7 @@ import UIKit
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
open private(set) var textField: TextField = {
|
open private(set) var textField: TextField = {
|
||||||
let textField = TextField(frame: .zero)
|
let textField = TextField()
|
||||||
textField.isAccessibilityElement = true
|
textField.isAccessibilityElement = true
|
||||||
textField.setContentCompressionResistancePriority(.required, for: .vertical)
|
textField.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
textField.font = MFStyler.fontForTextField()
|
textField.font = MFStyler.fontForTextField()
|
||||||
@ -58,7 +58,7 @@ import UIKit
|
|||||||
get { return super.isEnabled }
|
get { return super.isEnabled }
|
||||||
set (enabled) {
|
set (enabled) {
|
||||||
super.isEnabled = enabled
|
super.isEnabled = enabled
|
||||||
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
@ -85,7 +85,10 @@ import UIKit
|
|||||||
/// The text of this TextField.
|
/// The text of this TextField.
|
||||||
open override var text: String? {
|
open override var text: String? {
|
||||||
get { return textField.text }
|
get { return textField.text }
|
||||||
set { textField.text = newValue }
|
set {
|
||||||
|
textField.text = newValue
|
||||||
|
(model as? TextEntryFieldModel)?.text = newValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Placeholder access for the TextField.
|
/// Placeholder access for the TextField.
|
||||||
@ -99,7 +102,7 @@ import UIKit
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public var validationBlock: ((_ value: String?) -> Bool)?
|
public var validationBlock: ((_ value: String?) -> Bool)?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Delegate Properties
|
// MARK: - Delegate Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -169,6 +172,9 @@ import UIKit
|
|||||||
textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 16)
|
textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 16)
|
||||||
textFieldTrailingConstraint?.isActive = true
|
textFieldTrailingConstraint?.isActive = true
|
||||||
|
|
||||||
|
textField.addTarget(self, action: #selector(startEditing), for: .editingDidBegin)
|
||||||
|
textField.addTarget(self, action: #selector(dismissFieldInput(_:)), for: .editingDidEnd)
|
||||||
|
|
||||||
let tap = UITapGestureRecognizer(target: self, action: #selector(startEditing))
|
let tap = UITapGestureRecognizer(target: self, action: #selector(startEditing))
|
||||||
entryFieldContainer.addGestureRecognizer(tap)
|
entryFieldContainer.addGestureRecognizer(tap)
|
||||||
|
|
||||||
@ -225,7 +231,7 @@ import UIKit
|
|||||||
/// Validates the text of the entry field.
|
/// Validates the text of the entry field.
|
||||||
@discardableResult
|
@discardableResult
|
||||||
@objc public func validateTextField() -> Bool {
|
@objc public func validateTextField() -> Bool {
|
||||||
|
|
||||||
isValid = validationBlock?(text) ?? true
|
isValid = validationBlock?(text) ?? true
|
||||||
|
|
||||||
if isValid {
|
if isValid {
|
||||||
@ -277,7 +283,7 @@ import UIKit
|
|||||||
guard let model = model as? TextEntryFieldModel else { return }
|
guard let model = model as? TextEntryFieldModel else { return }
|
||||||
|
|
||||||
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
|
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
|
||||||
|
|
||||||
textColor.enabled = model.enabledTextColor?.uiColor
|
textColor.enabled = model.enabledTextColor?.uiColor
|
||||||
textColor.disabled = model.disabledTextColor?.uiColor
|
textColor.disabled = model.disabledTextColor?.uiColor
|
||||||
text = model.text
|
text = model.text
|
||||||
|
|||||||
@ -220,17 +220,27 @@ public typealias ActionBlock = () -> ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
|
||||||
clauses = []
|
clauses = []
|
||||||
guard let labelModel = model as? LabelModel else { return }
|
|
||||||
|
guard let labelModel = model as? LabelModel else {
|
||||||
|
text = ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
attributedText = nil
|
attributedText = nil
|
||||||
|
originalAttributedString = nil
|
||||||
text = labelModel.text
|
text = labelModel.text
|
||||||
Label.setLabel(self, withHTML: labelModel.html)
|
Label.setLabel(self, withHTML: labelModel.html)
|
||||||
|
|
||||||
let alignment = LabelAlignment(rawValue: labelModel.textAlignment ?? "")
|
let alignment = LabelAlignment(rawValue: labelModel.textAlignment ?? "")
|
||||||
switch alignment {
|
switch alignment {
|
||||||
case .center:
|
case .center:
|
||||||
textAlignment = .center
|
textAlignment = .center
|
||||||
|
|
||||||
case .right:
|
case .right:
|
||||||
textAlignment = .right
|
textAlignment = .right
|
||||||
|
|
||||||
default:
|
default:
|
||||||
textAlignment = .left
|
textAlignment = .left
|
||||||
}
|
}
|
||||||
@ -239,9 +249,11 @@ public typealias ActionBlock = () -> ()
|
|||||||
if let backgroundColor = labelModel.backgroundColor {
|
if let backgroundColor = labelModel.backgroundColor {
|
||||||
self.backgroundColor = backgroundColor.uiColor
|
self.backgroundColor = backgroundColor.uiColor
|
||||||
}
|
}
|
||||||
|
|
||||||
if let accessibilityText = labelModel.accessibilityText {
|
if let accessibilityText = labelModel.accessibilityText {
|
||||||
accessibilityLabel = accessibilityText
|
accessibilityLabel = accessibilityText
|
||||||
}
|
}
|
||||||
|
|
||||||
if let fontStyle = labelModel.fontStyle {
|
if let fontStyle = labelModel.fontStyle {
|
||||||
MFStyler.styleLabel(self, withStyle: fontStyle)
|
MFStyler.styleLabel(self, withStyle: fontStyle)
|
||||||
MFStyler.styleLabel(self, withStyle: fontStyle, genericScaling: false)
|
MFStyler.styleLabel(self, withStyle: fontStyle, genericScaling: false)
|
||||||
@ -264,19 +276,23 @@ public typealias ActionBlock = () -> ()
|
|||||||
|
|
||||||
if let attributes = labelModel.attributes, let labelText = text {
|
if let attributes = labelModel.attributes, let labelText = text {
|
||||||
let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: font.withSize(standardFontSize), NSAttributedString.Key.foregroundColor: textColor as UIColor])
|
let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: font.withSize(standardFontSize), NSAttributedString.Key.foregroundColor: textColor as UIColor])
|
||||||
|
|
||||||
for attribute in attributes {
|
for attribute in attributes {
|
||||||
let range = NSRange(location: attribute.location, length: attribute.length)
|
let range = NSRange(location: attribute.location, length: attribute.length)
|
||||||
switch attribute {
|
switch attribute {
|
||||||
case _ as LabelAttributeUnderlineModel:
|
case _ as LabelAttributeUnderlineModel:
|
||||||
attributedString.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range)
|
attributedString.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range)
|
||||||
|
|
||||||
case _ as LabelAttributeStrikeThroughModel:
|
case _ as LabelAttributeStrikeThroughModel:
|
||||||
attributedString.addAttribute(.strikethroughStyle, value: NSUnderlineStyle.thick.rawValue, range: range)
|
attributedString.addAttribute(.strikethroughStyle, value: NSUnderlineStyle.thick.rawValue, range: range)
|
||||||
attributedString.addAttribute(.baselineOffset, value: 0, range: range)
|
attributedString.addAttribute(.baselineOffset, value: 0, range: range)
|
||||||
|
|
||||||
case let colorAtt as LabelAttributeColorModel:
|
case let colorAtt as LabelAttributeColorModel:
|
||||||
if let colorHex = colorAtt.textColor, !colorHex.isEmpty {
|
if let colorHex = colorAtt.textColor, !colorHex.isEmpty {
|
||||||
attributedString.removeAttribute(.foregroundColor, range: range)
|
attributedString.removeAttribute(.foregroundColor, range: range)
|
||||||
attributedString.addAttribute(.foregroundColor, value: UIColor.mfGet(forHex: colorHex), range: range)
|
attributedString.addAttribute(.foregroundColor, value: UIColor.mfGet(forHex: colorHex), range: range)
|
||||||
}
|
}
|
||||||
|
|
||||||
case let imageAtt as LabelAttributeImageModel:
|
case let imageAtt as LabelAttributeImageModel:
|
||||||
var fontSize = font.pointSize
|
var fontSize = font.pointSize
|
||||||
if let attributeSize = imageAtt.size {
|
if let attributeSize = imageAtt.size {
|
||||||
@ -293,6 +309,7 @@ public typealias ActionBlock = () -> ()
|
|||||||
let mutableString = NSMutableAttributedString()
|
let mutableString = NSMutableAttributedString()
|
||||||
mutableString.append(NSAttributedString(attachment: imageAttachment))
|
mutableString.append(NSAttributedString(attachment: imageAttachment))
|
||||||
attributedString.insert(mutableString, at: imageAtt.location)
|
attributedString.insert(mutableString, at: imageAtt.location)
|
||||||
|
|
||||||
case let fontAtt as LabelAttributeFontModel:
|
case let fontAtt as LabelAttributeFontModel:
|
||||||
if let fontStyle = fontAtt.style {
|
if let fontStyle = fontAtt.style {
|
||||||
let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle)
|
let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle)
|
||||||
@ -320,6 +337,7 @@ public typealias ActionBlock = () -> ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
addActionAttributes(range: range, string: attributedString)
|
addActionAttributes(range: range, string: attributedString)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -381,8 +399,9 @@ public typealias ActionBlock = () -> ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let attributes = json?.optionalArrayForKey("attributes"), let labelText = label.text {
|
if let attributes = json?.optionalArrayForKey("attributes"), let labelText = label.text {
|
||||||
let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: mvmLabel?.font.withSize(mvmLabel!.standardFontSize) ?? label.font as UIFont,
|
let attributedString = NSMutableAttributedString(string: labelText,
|
||||||
NSAttributedString.Key.foregroundColor: label.textColor as UIColor])
|
attributes: [NSAttributedString.Key.font: mvmLabel?.font.withSize(mvmLabel!.standardFontSize) ?? label.font as UIFont,
|
||||||
|
NSAttributedString.Key.foregroundColor: label.textColor as UIColor])
|
||||||
for case let attribute as [String: Any] in attributes {
|
for case let attribute as [String: Any] in attributes {
|
||||||
guard let attributeType = attribute.optionalStringForKey(KeyType),
|
guard let attributeType = attribute.optionalStringForKey(KeyType),
|
||||||
let location = attribute["location"] as? Int,
|
let location = attribute["location"] as? Int,
|
||||||
|
|||||||
@ -48,19 +48,19 @@ import Foundation
|
|||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
self.moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName)
|
moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName)
|
||||||
self.text = try typeContainer.decode(String.self, forKey: .text)
|
text = try typeContainer.decode(String.self, forKey: .text)
|
||||||
self.accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||||
self.textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor)
|
textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor)
|
||||||
self.backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
self.fontStyle = try typeContainer.decodeIfPresent(String.self, forKey: .fontStyle)
|
fontStyle = try typeContainer.decodeIfPresent(String.self, forKey: .fontStyle)
|
||||||
self.fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName)
|
fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName)
|
||||||
self.fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize)
|
fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize)
|
||||||
self.textAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .textAlignment)
|
textAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .textAlignment)
|
||||||
self.attributes = try typeContainer.decodeModelsIfPresent(codingKey: .attributes, typeCodingKey: AttributeTypeKey.type) as? [LabelAttributeModel]
|
attributes = try typeContainer.decodeModelsIfPresent(codingKey: .attributes, typeCodingKey: AttributeTypeKey.type) as? [LabelAttributeModel]
|
||||||
self.html = try typeContainer.decodeIfPresent(String.self, forKey: .html)
|
html = try typeContainer.decodeIfPresent(String.self, forKey: .html)
|
||||||
self.hero = try typeContainer.decodeIfPresent(Int.self, forKey: .hero)
|
hero = try typeContainer.decodeIfPresent(Int.self, forKey: .hero)
|
||||||
self.makeWholeViewClickable = try typeContainer.decodeIfPresent(Bool.self, forKey: .makeWholeViewClickable)
|
makeWholeViewClickable = try typeContainer.decodeIfPresent(Bool.self, forKey: .makeWholeViewClickable)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
|||||||
@ -31,7 +31,7 @@ import UIKit
|
|||||||
view.translatesAutoresizingMaskIntoConstraints = false
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
addSubview(view)
|
addSubview(view)
|
||||||
view.backgroundColor = progressObject.progressColor.uiColor
|
view.backgroundColor = progressObject.progressColor.uiColor
|
||||||
view.widthAnchor.constraint(equalTo: widthAnchor, multiplier: progressObject.progress).isActive = true
|
view.widthAnchor.constraint(equalTo: widthAnchor, multiplier: progressObject.progress/100.0).isActive = true
|
||||||
view.leadingAnchor.constraint(equalTo: previous?.trailingAnchor ?? leadingAnchor).isActive = true
|
view.leadingAnchor.constraint(equalTo: previous?.trailingAnchor ?? leadingAnchor).isActive = true
|
||||||
previous = view
|
previous = view
|
||||||
NSLayoutConstraint.constraintPinSubview(view, pinTop: true, pinBottom: true, pinLeft: false, pinRight: false)
|
NSLayoutConstraint.constraintPinSubview(view, pinTop: true, pinBottom: true, pinLeft: false, pinRight: false)
|
||||||
|
|||||||
@ -68,9 +68,8 @@ open class ThreeLayerTableViewController: MFProgrammaticTableViewController {
|
|||||||
|
|
||||||
open override func updateViewConstraints() {
|
open override func updateViewConstraints() {
|
||||||
super.updateViewConstraints()
|
super.updateViewConstraints()
|
||||||
guard let tableView = tableView else {
|
|
||||||
return
|
guard let tableView = tableView else { return }
|
||||||
}
|
|
||||||
|
|
||||||
let minimumSpace: CGFloat = minimumFillSpace()
|
let minimumSpace: CGFloat = minimumFillSpace()
|
||||||
var currentSpace: CGFloat = 0
|
var currentSpace: CGFloat = 0
|
||||||
@ -90,9 +89,8 @@ open class ThreeLayerTableViewController: MFProgrammaticTableViewController {
|
|||||||
totalMinimumSpace += minimumSpace
|
totalMinimumSpace += minimumSpace
|
||||||
}
|
}
|
||||||
|
|
||||||
guard fillTop || fillBottom else {
|
guard fillTop || fillBottom else { return }
|
||||||
return
|
|
||||||
}
|
|
||||||
let newSpace = MVMCoreUIUtility.getVariableConstraintHeight(currentSpace, in: tableView, minimumHeight: totalMinimumSpace)
|
let newSpace = MVMCoreUIUtility.getVariableConstraintHeight(currentSpace, in: tableView, minimumHeight: totalMinimumSpace)
|
||||||
|
|
||||||
// If the bottom view is outside of the scroll, then only the top view constraint is being used, so we have to double it to account for the bottom constraint not being there when we compare to the new value.
|
// If the bottom view is outside of the scroll, then only the top view constraint is being used, so we have to double it to account for the bottom constraint not being there when we compare to the new value.
|
||||||
|
|||||||
26
MVMCoreUI/Legacy/Views/MFCaretButton.h
Normal file
26
MVMCoreUI/Legacy/Views/MFCaretButton.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// MFCaretButton.h
|
||||||
|
// MobileFirstFramework
|
||||||
|
//
|
||||||
|
// Created by Kolli, Praneeth on 1/5/18.
|
||||||
|
// Copyright © 2018 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <MVMCoreUI/MFCustomButton.h>
|
||||||
|
|
||||||
|
@interface MFCaretButton : MFCustomButton
|
||||||
|
|
||||||
|
@property (nullable, nonatomic, strong) UIView *rightView;
|
||||||
|
@property (nullable, nonatomic, strong) NSNumber *rightViewHeight;
|
||||||
|
@property (nullable, nonatomic, strong) NSNumber *rightViewWidth;
|
||||||
|
|
||||||
|
-(void)updateCaretSpacing:(CGFloat)spacing;
|
||||||
|
|
||||||
|
/* The fill color of the Caret and titleLabel. The default is blackColor */
|
||||||
|
-(void)setEnableCaretColor:(nullable UIColor *)enableCaretColor;
|
||||||
|
|
||||||
|
/* The fill color of the Caret and titleLabel. The default is mfSilver */
|
||||||
|
-(void)setDisabledCaretColor:(nullable UIColor *)disabledCaretColor;
|
||||||
|
|
||||||
|
@end
|
||||||
113
MVMCoreUI/Legacy/Views/MFCaretButton.m
Normal file
113
MVMCoreUI/Legacy/Views/MFCaretButton.m
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
//
|
||||||
|
// MFCaretButton.m
|
||||||
|
// MobileFirstFramework
|
||||||
|
//
|
||||||
|
// Created by Kolli, Praneeth on 1/5/18.
|
||||||
|
// Copyright © 2018 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MFCaretButton.h"
|
||||||
|
#import "MFCaretView.h"
|
||||||
|
#import "UIColor+MFConvenience.h"
|
||||||
|
|
||||||
|
@interface MFCaretButton ()
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIColor *enableColor;
|
||||||
|
@property (nonatomic, strong) UIColor *disabledColor;
|
||||||
|
@property (nonatomic, strong) NSLayoutConstraint *caretSpacingConstraint;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MFCaretButton
|
||||||
|
|
||||||
|
CGFloat const CaretViewHeight = 10.8f;
|
||||||
|
CGFloat const CaretViewWidth = 6.6f;
|
||||||
|
|
||||||
|
|
||||||
|
- (void)layoutSubviews {
|
||||||
|
[self addCaretImageView];
|
||||||
|
[super layoutSubviews];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setEnabled:(BOOL)enabled {
|
||||||
|
[super setEnabled:enabled];
|
||||||
|
[self changeCaretColor];
|
||||||
|
}
|
||||||
|
- (void)changeCaretColor {
|
||||||
|
[self setTitleColor:self.enableColor forState:UIControlStateNormal];
|
||||||
|
[self setTitleColor:self.disabledColor forState:UIControlStateDisabled];
|
||||||
|
if ([self.rightView isKindOfClass:[MFCaretView class]]) {
|
||||||
|
MFCaretView *caretView = (MFCaretView *)self.rightView;
|
||||||
|
if (self.enabled) {
|
||||||
|
[caretView setLineColor:self.enableColor];
|
||||||
|
} else {
|
||||||
|
[caretView setLineColor:self.disabledColor];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addCaretImageView {
|
||||||
|
[self.rightView removeFromSuperview];
|
||||||
|
UIEdgeInsets edgeInsets = self.contentEdgeInsets;
|
||||||
|
CGFloat rightInset = self.rightViewWidth?self.rightViewWidth.floatValue:CaretViewWidth;
|
||||||
|
UIEdgeInsets newInsets = UIEdgeInsetsMake(edgeInsets.top, edgeInsets.left, edgeInsets.bottom, 4 + rightInset);
|
||||||
|
self.contentEdgeInsets = newInsets;
|
||||||
|
UIView *caretViewIs = self.rightView;
|
||||||
|
if (!self.rightView) {
|
||||||
|
caretViewIs = [[MFCaretView alloc]init];
|
||||||
|
self.rightView = caretViewIs;
|
||||||
|
}
|
||||||
|
self.rightView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||||
|
[self addSubview:self.rightView];
|
||||||
|
|
||||||
|
CGFloat width = self.rightViewWidth?self.rightViewWidth.floatValue:CaretViewWidth;
|
||||||
|
NSLayoutConstraint *caretViewWidthConstraint = [NSLayoutConstraint constraintWithItem:caretViewIs attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:width];
|
||||||
|
caretViewWidthConstraint.active = YES;
|
||||||
|
|
||||||
|
CGFloat height = self.rightViewHeight?self.rightViewHeight.floatValue:CaretViewHeight;
|
||||||
|
NSLayoutConstraint *caretViewHeightConstraint = [NSLayoutConstraint constraintWithItem:caretViewIs attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:height];
|
||||||
|
caretViewHeightConstraint.active = YES;
|
||||||
|
|
||||||
|
NSLayoutConstraint *caretLabelSpacing = [NSLayoutConstraint constraintWithItem:caretViewIs attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.titleLabel attribute:NSLayoutAttributeRight multiplier:1.0 constant:4.0];
|
||||||
|
caretLabelSpacing.active = YES;
|
||||||
|
self.caretSpacingConstraint = caretLabelSpacing;
|
||||||
|
|
||||||
|
NSLayoutConstraint *caretCenterY = [NSLayoutConstraint constraintWithItem:caretViewIs attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0];
|
||||||
|
caretCenterY.active = YES;
|
||||||
|
|
||||||
|
NSLayoutConstraint *caretLabelRightPin = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:caretViewIs attribute:NSLayoutAttributeRight multiplier:1.0 constant:0];
|
||||||
|
caretLabelRightPin.active = YES;
|
||||||
|
self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
|
||||||
|
//set correct color after layout
|
||||||
|
[self changeCaretColor];
|
||||||
|
}
|
||||||
|
- (void)updateCaretSpacing:(CGFloat)spacing {
|
||||||
|
if (self.caretSpacingConstraint != nil) {
|
||||||
|
self.caretSpacingConstraint.constant = spacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- (void)setEnableCaretColor:(UIColor *)enableCaretColor {
|
||||||
|
self.enableColor = enableCaretColor;
|
||||||
|
[self changeCaretColor];
|
||||||
|
}
|
||||||
|
- (void)setDisabledCaretColor:(UIColor *)disabledCaretColor {
|
||||||
|
self.disabledColor = disabledCaretColor;
|
||||||
|
[self changeCaretColor];
|
||||||
|
}
|
||||||
|
@synthesize enableColor = _enableColor;
|
||||||
|
- (UIColor *)enableColor {
|
||||||
|
if (!_enableColor) {
|
||||||
|
_enableColor = [UIColor blackColor];
|
||||||
|
}
|
||||||
|
return _enableColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@synthesize disabledColor = _disabledColor;
|
||||||
|
- (UIColor *)disabledColor {
|
||||||
|
if (!_disabledColor) {
|
||||||
|
_disabledColor = [UIColor mfSilver];
|
||||||
|
}
|
||||||
|
return _disabledColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
16
MVMCoreUI/Legacy/Views/MFCaretView.h
Normal file
16
MVMCoreUI/Legacy/Views/MFCaretView.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// MFCaretView.h
|
||||||
|
// MobileFirstFramework
|
||||||
|
//
|
||||||
|
// Created by Kolli, Praneeth on 1/5/18.
|
||||||
|
// Copyright © 2018 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface MFCaretView : UIView
|
||||||
|
@property (strong, nonatomic, readonly) UIColor *strokeColor;
|
||||||
|
- (instancetype)initWithLineWidth:(CGFloat)lineWidth;
|
||||||
|
- (void)setLineColor:(UIColor *)color;
|
||||||
|
@end
|
||||||
|
|
||||||
93
MVMCoreUI/Legacy/Views/MFCaretView.m
Normal file
93
MVMCoreUI/Legacy/Views/MFCaretView.m
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
//
|
||||||
|
// MFCaretView.m
|
||||||
|
// MobileFirstFramework
|
||||||
|
//
|
||||||
|
// Created by Kolli, Praneeth on 1/5/18.
|
||||||
|
// Copyright © 2018 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MFCaretView.h"
|
||||||
|
#import "UIColor+MFConvenience.h"
|
||||||
|
@interface MFCaretView ()
|
||||||
|
@property (strong, nonatomic, readwrite) UIColor *strokeColor;
|
||||||
|
@property (nonatomic) NSNumber *lineWidth;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MFCaretView
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
// Initialization code
|
||||||
|
self.opaque = NO;
|
||||||
|
self.backgroundColor = [UIColor clearColor];
|
||||||
|
self.strokeColor = [UIColor blackColor];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithFrame:(CGRect)frame {
|
||||||
|
self = [super initWithFrame:frame];
|
||||||
|
if (self) {
|
||||||
|
// Initialization code
|
||||||
|
self.opaque = NO;
|
||||||
|
self.backgroundColor = [UIColor clearColor];
|
||||||
|
self.strokeColor = [UIColor blackColor];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||||
|
self = [super initWithCoder:aDecoder];
|
||||||
|
if (self) {
|
||||||
|
// Initialization code
|
||||||
|
self.opaque = NO;
|
||||||
|
self.backgroundColor = [UIColor clearColor];
|
||||||
|
self.strokeColor = [UIColor blackColor];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithLineWidth:(CGFloat)lineWidth {
|
||||||
|
if (self = [super init]) {
|
||||||
|
self.opaque = NO;
|
||||||
|
self.backgroundColor = [UIColor clearColor];
|
||||||
|
self.lineWidth = @(lineWidth);
|
||||||
|
self.strokeColor = [UIColor blackColor];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)drawRect:(CGRect)rect {
|
||||||
|
// Drawing Caret
|
||||||
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||||
|
CGContextClearRect(context, rect);
|
||||||
|
|
||||||
|
CGFloat lineWidth;
|
||||||
|
if (self.lineWidth) {
|
||||||
|
lineWidth = self.lineWidth.floatValue;
|
||||||
|
} else {
|
||||||
|
lineWidth = self.frame.size.width/2.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIBezierPath *path = [[UIBezierPath alloc] init];
|
||||||
|
[path moveToPoint:CGPointMake(lineWidth/2.0, 0.0)];
|
||||||
|
[path addLineToPoint:CGPointMake(self.frame.size.width, self.frame.size.height/2.0)];
|
||||||
|
[path addLineToPoint:CGPointMake(lineWidth/2.0, self.frame.size.height)];
|
||||||
|
[path addLineToPoint:CGPointMake(0.0, self.frame.size.height-lineWidth/2.0)];
|
||||||
|
[path addLineToPoint:CGPointMake(self.frame.size.width-lineWidth, self.frame.size.height/2.0)];
|
||||||
|
[path addLineToPoint:CGPointMake(0.0, lineWidth/2.0)];
|
||||||
|
[path addLineToPoint:CGPointMake(lineWidth/2.0, 0.0)];
|
||||||
|
[self.strokeColor setFill];
|
||||||
|
[path fill];
|
||||||
|
[path closePath];
|
||||||
|
[self setBackgroundColor:[UIColor clearColor]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setLineColor:(UIColor *)color {
|
||||||
|
self.strokeColor = color;
|
||||||
|
[self setNeedsDisplay];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@ -81,6 +81,7 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[];
|
|||||||
#import <MVMCoreUI/MVMCoreUICheckBox.h>
|
#import <MVMCoreUI/MVMCoreUICheckBox.h>
|
||||||
#import <MVMCoreUI/MVMCoreUISwitch.h>
|
#import <MVMCoreUI/MVMCoreUISwitch.h>
|
||||||
#import <MVMCoreUI/MFRadioButton.h>
|
#import <MVMCoreUI/MFRadioButton.h>
|
||||||
|
#import <MVMCoreUI/MFCaretView.h>
|
||||||
|
|
||||||
#pragma mark Buttons
|
#pragma mark Buttons
|
||||||
#import <MVMCoreUI/MFButtonProtocol.h>
|
#import <MVMCoreUI/MFButtonProtocol.h>
|
||||||
@ -89,6 +90,7 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[];
|
|||||||
#import <MVMCoreUI/PrimaryButton.h>
|
#import <MVMCoreUI/PrimaryButton.h>
|
||||||
#import <MVMCoreUI/MFTextButton.h>
|
#import <MVMCoreUI/MFTextButton.h>
|
||||||
#import <MVMCoreUI/PrimaryButtonView.h>
|
#import <MVMCoreUI/PrimaryButtonView.h>
|
||||||
|
#import <MVMCoreUI/MFCaretButton.h>
|
||||||
|
|
||||||
#pragma mark TextFields
|
#pragma mark TextFields
|
||||||
#import <MVMCoreUI/MFTextField.h>
|
#import <MVMCoreUI/MFTextField.h>
|
||||||
|
|||||||
@ -17,19 +17,14 @@ public protocol ListItemModelProtocol: ContainerModelProtocol, MoleculeModelProt
|
|||||||
|
|
||||||
// Not a strict requirement.
|
// Not a strict requirement.
|
||||||
extension ListItemModelProtocol {
|
extension ListItemModelProtocol {
|
||||||
|
|
||||||
public var action: ActionModelProtocol? {
|
public var action: ActionModelProtocol? {
|
||||||
get {
|
get { return nil }
|
||||||
return nil
|
set { }
|
||||||
}
|
|
||||||
set {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var style: String? {
|
public var style: String? {
|
||||||
get {
|
get { return nil }
|
||||||
return nil
|
set { }
|
||||||
}
|
|
||||||
set {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@objcMembers open class TwoButtonView: ViewConstrainingView {
|
@objcMembers open class TwoButtonView: View, MVMCoreUIViewConstrainingProtocol {
|
||||||
open var primaryButton: PrimaryButton? = PrimaryButton.button()
|
open var primaryButton: PillButton = PillButton()
|
||||||
open var secondaryButton: PrimaryButton? = PrimaryButton.button()
|
open var secondaryButton: PillButton = PillButton()
|
||||||
open var viewForButtons: UIView?
|
private var stack = UIStackView()
|
||||||
public var heightConstraint: NSLayoutConstraint?
|
private var equalWidthConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
}
|
}
|
||||||
@ -26,289 +26,100 @@ import UIKit
|
|||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func setDefaultCustom() {
|
public func setDefault() {
|
||||||
primaryButton?.setAsStandardCustom()
|
primaryButton.stylePrimary()
|
||||||
secondaryButton?.setAsSecondaryCustom()
|
secondaryButton.styleSecondary()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MVMCoreViewProtocol
|
// MARK: - MVMCoreViewProtocol
|
||||||
open override func updateView(_ size: CGFloat) {
|
open override func updateView(_ size: CGFloat) {
|
||||||
super.updateView(size)
|
super.updateView(size)
|
||||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
self.primaryButton.updateView(size)
|
||||||
self.primaryButton?.updateView(size)
|
self.secondaryButton.updateView(size)
|
||||||
self.secondaryButton?.updateView(size)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func setupView() {
|
open override func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
setupWithTwoButtons()
|
|
||||||
secondaryButton?.bordered = true
|
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
addSubview(stack)
|
||||||
|
stack.addArrangedSubview(secondaryButton)
|
||||||
|
stack.addArrangedSubview(primaryButton)
|
||||||
|
NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
|
||||||
|
stack.axis = .horizontal
|
||||||
|
stack.spacing = 10
|
||||||
|
equalWidthConstraint = secondaryButton.widthAnchor.constraint(equalTo: primaryButton.widthAnchor, multiplier: 1)
|
||||||
|
equalWidthConstraint?.isActive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Stack Manipulation
|
||||||
|
public func showPrimaryButton() {
|
||||||
|
if !stack.arrangedSubviews.contains(primaryButton) {
|
||||||
|
stack.addArrangedSubview(primaryButton)
|
||||||
|
primaryButton.isHidden = false
|
||||||
|
}
|
||||||
|
if secondaryButton.superview != nil {
|
||||||
|
equalWidthConstraint?.isActive = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func showSecondaryButton() {
|
||||||
|
if !stack.arrangedSubviews.contains(secondaryButton) {
|
||||||
|
stack.insertArrangedSubview(secondaryButton, at: 0)
|
||||||
|
secondaryButton.isHidden = false
|
||||||
|
}
|
||||||
|
if primaryButton.superview != nil {
|
||||||
|
equalWidthConstraint?.isActive = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func hidePrimaryButton() {
|
||||||
|
if primaryButton.superview != nil {
|
||||||
|
stack.removeArrangedSubview(primaryButton)
|
||||||
|
primaryButton.isHidden = true
|
||||||
|
}
|
||||||
|
equalWidthConstraint?.isActive = false
|
||||||
|
}
|
||||||
|
|
||||||
|
public func hideSecondaryButton() {
|
||||||
|
if secondaryButton.superview != nil {
|
||||||
|
stack.removeArrangedSubview(secondaryButton)
|
||||||
|
secondaryButton.isHidden = true
|
||||||
|
}
|
||||||
|
equalWidthConstraint?.isActive = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
let primaryButtonMap = json?.optionalDictionaryForKey("primaryButton")
|
|
||||||
let secondaryButtonMap = json?.optionalDictionaryForKey("secondaryButton")
|
|
||||||
set(primaryButtonJSON: primaryButtonMap, secondaryButtonJSON: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
primaryButton?.setAsStandardCustom()
|
setDefault()
|
||||||
secondaryButton?.setAsSecondaryCustom()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Constraining
|
// MARK: - MVMCoreUIViewConstrainingProtocol
|
||||||
func createPrimaryButton() {
|
open func horizontalAlignment() -> UIStackView.Alignment {
|
||||||
if primaryButton == nil {
|
|
||||||
primaryButton = PrimaryButton.button()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func createSecondaryButton() {
|
|
||||||
if secondaryButton == nil {
|
|
||||||
secondaryButton = PrimaryButton.button()
|
|
||||||
secondaryButton?.bordered = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeButtons() {
|
|
||||||
viewForButtons?.removeFromSuperview()
|
|
||||||
primaryButton?.removeFromSuperview()
|
|
||||||
secondaryButton?.removeFromSuperview()
|
|
||||||
viewForButtons = nil
|
|
||||||
secondaryButton = nil
|
|
||||||
primaryButton = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
open func setupConstraintsForViewWithButtons() {
|
|
||||||
guard let viewForButtons = viewForButtons,
|
|
||||||
let primaryButton = primaryButton,
|
|
||||||
let secondaryButton = secondaryButton
|
|
||||||
else { return }
|
|
||||||
|
|
||||||
viewForButtons.addSubview(primaryButton)
|
|
||||||
viewForButtons.addSubview(secondaryButton)
|
|
||||||
secondaryButton.widthAnchor.constraint(equalTo: primaryButton.widthAnchor, multiplier: 1).isActive = true
|
|
||||||
NSLayoutConstraint.constraintPinSubview(secondaryButton, pinTop: true, pinBottom: true, pinLeft: true, pinRight: false)
|
|
||||||
NSLayoutConstraint.constraintPinSubview(primaryButton, pinTop: true, pinBottom: true, pinLeft: false, pinRight: true)
|
|
||||||
let constraint = primaryButton.leadingAnchor.constraint(equalTo: secondaryButton.trailingAnchor, constant: 10)
|
|
||||||
constraint.priority = UILayoutPriority(900)
|
|
||||||
constraint.isActive = true
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupWithTwoButtons() {
|
|
||||||
guard viewForButtons == nil else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let viewForButtons = MVMCoreUICommonViewsUtility.commonView()
|
|
||||||
addSubview(viewForButtons)
|
|
||||||
self.viewForButtons = viewForButtons
|
|
||||||
|
|
||||||
pinView(toSuperView: viewForButtons)
|
|
||||||
alignCenterHorizontal()
|
|
||||||
createPrimaryButton()
|
|
||||||
createSecondaryButton()
|
|
||||||
setupConstraintsForViewWithButtons()
|
|
||||||
}
|
|
||||||
|
|
||||||
open func setupWithPrimaryButton() {
|
|
||||||
guard primaryButton == nil && secondaryButton == nil else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
createPrimaryButton()
|
|
||||||
if let primaryButton = primaryButton {
|
|
||||||
addSubview(primaryButton)
|
|
||||||
pinView(toSuperView: primaryButton)
|
|
||||||
alignCenterHorizontal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open func setupWithSecondaryButton() {
|
|
||||||
guard secondaryButton == nil && primaryButton == nil else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
createSecondaryButton()
|
|
||||||
if let secondaryButton = secondaryButton {
|
|
||||||
addSubview(secondaryButton)
|
|
||||||
pinView(toSuperView: secondaryButton)
|
|
||||||
alignCenterHorizontal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Legacy
|
|
||||||
func setupUI(withPrimaryButtonMap primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?) {
|
|
||||||
setupUI(primaryButtonShowing: primaryButtonMap != nil, secondaryButtonShowing: secondaryButtonMap != nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupUI(primaryButtonShowing: Bool, secondaryButtonShowing: Bool) {
|
|
||||||
if primaryButtonShowing, secondaryButtonShowing {
|
|
||||||
heightConstraint?.isActive = false
|
|
||||||
if primaryButton == nil || secondaryButton == nil {
|
|
||||||
removeButtons()
|
|
||||||
setupWithTwoButtons()
|
|
||||||
}
|
|
||||||
} else if primaryButtonShowing {
|
|
||||||
heightConstraint?.isActive = false
|
|
||||||
if primaryButton == nil || secondaryButton != nil {
|
|
||||||
removeButtons()
|
|
||||||
setupWithPrimaryButton()
|
|
||||||
}
|
|
||||||
} else if secondaryButtonShowing {
|
|
||||||
heightConstraint?.isActive = false
|
|
||||||
if secondaryButton == nil || primaryButton != nil {
|
|
||||||
removeButtons()
|
|
||||||
setupWithSecondaryButton()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
removeButtons()
|
|
||||||
if heightConstraint == nil {
|
|
||||||
heightConstraint = heightAnchor.constraint(equalToConstant: 0)
|
|
||||||
heightConstraint?.isActive = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON)
|
|
||||||
setDefaultCustom()
|
|
||||||
primaryButton?.setWithJSON(primaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
secondaryButton?.setWithJSON(secondaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Legacy
|
|
||||||
public convenience init(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
self.init()
|
|
||||||
setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
public convenience init(buttonSmall small: Bool, buttonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: AnyHashable]?) {
|
|
||||||
self.init()
|
|
||||||
setup(withButtonMap: buttonMap, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
primaryButton?.setAsSmall(small)
|
|
||||||
secondaryButton?.setAsSmall(small)
|
|
||||||
}
|
|
||||||
|
|
||||||
public convenience init(buttonSmall small: Bool, enabled: Bool) {
|
|
||||||
self.init()
|
|
||||||
removeButtons()
|
|
||||||
setupWithPrimaryButton()
|
|
||||||
primaryButton?.setAsSmall(small)
|
|
||||||
primaryButton?.isEnabled = enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap)
|
|
||||||
if primaryButtonMap != nil, secondaryButtonMap != nil {
|
|
||||||
primaryButton?.setWithActionMap(primaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
secondaryButton?.setWithActionMap(secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
} else if primaryButtonMap != nil {
|
|
||||||
primaryButton?.setWithActionMap(primaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
primaryButton?.bordered = false
|
|
||||||
} else if secondaryButtonMap != nil {
|
|
||||||
secondaryButton?.setWithActionMap(secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
secondaryButton?.bordered = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton)
|
|
||||||
let primaryButtonMap = buttonMap?.optionalDictionaryForKey(KeyPrimaryButton)
|
|
||||||
setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func hideLeftButton() {
|
|
||||||
guard let secondaryButton = secondaryButton, !secondaryButton.isHidden else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
secondaryButton.isHidden = true
|
|
||||||
if let primaryButton = primaryButton {
|
|
||||||
primaryButton.removeFromSuperview()
|
|
||||||
viewForButtons?.addSubview(primaryButton)
|
|
||||||
NSLayoutConstraint.constraintPinSubview(toSuperview: primaryButton)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func hideRightButton() {
|
|
||||||
guard let primaryButton = primaryButton, !primaryButton.isHidden else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
primaryButton.isHidden = true
|
|
||||||
if let secondaryButton = secondaryButton {
|
|
||||||
secondaryButton.removeFromSuperview()
|
|
||||||
viewForButtons?.addSubview(secondaryButton)
|
|
||||||
NSLayoutConstraint.constraintPinSubview(toSuperview: secondaryButton)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func showBothButtons() {
|
|
||||||
primaryButton?.isHidden = false
|
|
||||||
secondaryButton?.isHidden = false
|
|
||||||
if let primaryButton = primaryButton, let secondaryButton = secondaryButton {
|
|
||||||
primaryButton.removeFromSuperview()
|
|
||||||
secondaryButton.removeFromSuperview()
|
|
||||||
setupConstraintsForViewWithButtons()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func hideBothButtons() {
|
|
||||||
primaryButton?.isHidden = true
|
|
||||||
secondaryButton?.isHidden = true
|
|
||||||
}
|
|
||||||
|
|
||||||
override open func horizontalAlignment() -> UIStackView.Alignment {
|
|
||||||
return .center
|
return .center
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// MARK: - ModelMoleculeViewProtocol
|
||||||
// MARK: - Deprecate
|
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
extension TwoButtonView {
|
guard let model = molecule as? TwoButtonViewModel else { return 0 }
|
||||||
@available(*, deprecated)
|
return PillButton.estimatedHeight(forRow: model.primaryButton ?? model.secondaryButton, delegateObject: delegateObject)
|
||||||
open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) {
|
}
|
||||||
setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap)
|
|
||||||
if primaryButtonMap != nil, secondaryButtonMap != nil {
|
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
super.setWithModel(model, delegateObject, additionalData)
|
||||||
secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
guard let model = model as? TwoButtonViewModel else { return }
|
||||||
} else if primaryButtonMap != nil {
|
if let secondaryModel = model.secondaryButton {
|
||||||
primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
showSecondaryButton()
|
||||||
primaryButton?.bordered = false
|
secondaryButton.setWithModel(secondaryModel, delegateObject, additionalData)
|
||||||
} else if secondaryButtonMap != nil {
|
} else {
|
||||||
secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
hideSecondaryButton()
|
||||||
secondaryButton?.bordered = true
|
}
|
||||||
|
if let primaryModel = model.primaryButton {
|
||||||
|
showPrimaryButton()
|
||||||
|
primaryButton.setWithModel(primaryModel, delegateObject, additionalData)
|
||||||
|
} else {
|
||||||
|
hidePrimaryButton()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(*, deprecated)
|
|
||||||
open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) {
|
|
||||||
let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton)
|
|
||||||
let primaryButtonMap = buttonMap?.optionalDictionaryForKey(KeyPrimaryButton)
|
|
||||||
setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate)
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(*, deprecated)
|
|
||||||
public convenience init(buttonSmall small: Bool, buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: AnyHashable]?, buttonDelegate: Any?) {
|
|
||||||
self.init()
|
|
||||||
setup(withButtonMap: buttonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate)
|
|
||||||
primaryButton?.setAsSmall(small)
|
|
||||||
secondaryButton?.setAsSmall(small)
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(*, deprecated)
|
|
||||||
public convenience init(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) {
|
|
||||||
self.init()
|
|
||||||
setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension TwoButtonView: ModelMoleculeViewProtocol {
|
|
||||||
public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
|
||||||
guard let model = model as? TwoButtonViewModel else { return }
|
|
||||||
setupUI(primaryButtonShowing: model.primaryButton != nil, secondaryButtonShowing: model.secondaryButton != nil)
|
|
||||||
setDefaultCustom()
|
|
||||||
primaryButton?.setWithModel(model.primaryButton, delegateObject, additionalData)
|
|
||||||
secondaryButton?.setWithModel(model.secondaryButton, delegateObject, additionalData)
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,9 +8,35 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
public struct TwoButtonViewModel: MoleculeModelProtocol {
|
public class TwoButtonViewModel: MoleculeModelProtocol {
|
||||||
public static var identifier: String = "twoButtonView"
|
public static var identifier: String = "twoButtonView"
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var primaryButton: ButtonModel?
|
public var primaryButton: ButtonModel?
|
||||||
public var secondaryButton: ButtonModel?
|
public var secondaryButton: ButtonModel?
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case backgroundColor
|
||||||
|
case primaryButton
|
||||||
|
case secondaryButton
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
|
primaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .primaryButton)
|
||||||
|
secondaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .secondaryButton)
|
||||||
|
// Default value
|
||||||
|
if secondaryButton?.style == nil {
|
||||||
|
secondaryButton?.style = .secondary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(primaryButton, forKey: .primaryButton)
|
||||||
|
try container.encodeIfPresent(secondaryButton, forKey: .secondaryButton)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import UIKit
|
|||||||
super.setupView()
|
super.setupView()
|
||||||
|
|
||||||
guard dropDown.superview == nil else { return }
|
guard dropDown.superview == nil else { return }
|
||||||
|
|
||||||
addMolecule(dropDown)
|
addMolecule(dropDown)
|
||||||
dropDown.observeDropdownChange = { [weak self] oldValue, newValue in
|
dropDown.observeDropdownChange = { [weak self] oldValue, newValue in
|
||||||
|
|
||||||
|
|||||||
@ -8,14 +8,19 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
|
||||||
@objcMembers open class MoleculeTableViewCell: TableViewCell {
|
@objcMembers open class MoleculeTableViewCell: TableViewCell {
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||||
|
|
||||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.setWithModel(model, delegateObject, additionalData)
|
super.setWithModel(model, delegateObject, additionalData)
|
||||||
|
|
||||||
guard let model = model as? ListItemModel else { return }
|
guard let model = model as? ListItemModel else { return }
|
||||||
|
|
||||||
if molecule != nil {
|
if molecule != nil {
|
||||||
(molecule as? ModelMoleculeViewProtocol)?.setWithModel(model.molecule, delegateObject, additionalData)
|
(molecule as? ModelMoleculeViewProtocol)?.setWithModel(model.molecule, delegateObject, additionalData)
|
||||||
|
|
||||||
} else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(model.molecule, delegateObject, false) {
|
} else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(model.molecule, delegateObject, false) {
|
||||||
addMolecule(moleculeView)
|
addMolecule(moleculeView)
|
||||||
}
|
}
|
||||||
@ -24,28 +29,28 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
public override class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||||
guard let moleculeModel = (model as? ListItemModel)?.molecule else {
|
guard let moleculeModel = (model as? ListItemModel)?.molecule else { return "\(self)<>" }
|
||||||
return "\(self)<>"
|
|
||||||
}
|
|
||||||
let className = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type
|
let className = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type
|
||||||
let moleculeName = className?.nameForReuse(moleculeModel, delegateObject) ?? moleculeModel.moleculeName ?? ""
|
let moleculeName = className?.nameForReuse(moleculeModel, delegateObject) ?? moleculeModel.moleculeName ?? ""
|
||||||
|
|
||||||
return "\(self)<\(moleculeName)>"
|
return "\(self)<\(moleculeName)>"
|
||||||
}
|
}
|
||||||
|
|
||||||
public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
||||||
guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule),
|
guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule),
|
||||||
let theClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON) else {
|
let theClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON)
|
||||||
return nil
|
else { return nil }
|
||||||
}
|
|
||||||
return theClass.requiredModules?(moleculeJSON, delegateObject: delegateObject, error: error)
|
return theClass.requiredModules?(moleculeJSON, delegateObject: delegateObject, error: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||||
guard let moleculeModel = (molecule as? MoleculeContainerModel)?.molecule,
|
guard let moleculeModel = (molecule as? MoleculeContainerModel)?.molecule,
|
||||||
let classType = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type,
|
let classType = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type,
|
||||||
let height = classType.estimatedHeight(forRow: moleculeModel, delegateObject: delegateObject) else {
|
let height = classType.estimatedHeight(forRow: moleculeModel, delegateObject: delegateObject)
|
||||||
return 80
|
else { return 80 }
|
||||||
}
|
|
||||||
return max(2 * PaddingDefaultVerticalSpacing3, height)
|
return max(2 * PaddingDefaultVerticalSpacing3, height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -171,10 +171,8 @@ import UIKit
|
|||||||
guard let model = model as? CornerLabelsModel else { return }
|
guard let model = model as? CornerLabelsModel else { return }
|
||||||
if middleView != nil {
|
if middleView != nil {
|
||||||
(middleView as? ModelMoleculeViewProtocol)?.setWithModel(model, delegateObject, additionalData)
|
(middleView as? ModelMoleculeViewProtocol)?.setWithModel(model, delegateObject, additionalData)
|
||||||
} else {
|
} else if let moleculeModel = model.molecule, let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(moleculeModel, delegateObject) {
|
||||||
if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(model.molecule, delegateObject) {
|
addMiddleView(molecule)
|
||||||
addMiddleView(molecule)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
topLeftLabel.setWithModel(model.topLeftLabel, delegateObject, additionalData)
|
topLeftLabel.setWithModel(model.topLeftLabel, delegateObject, additionalData)
|
||||||
|
|||||||
@ -15,9 +15,9 @@ public class CornerLabelsModel: MoleculeModelProtocol {
|
|||||||
public var topRightLabel: LabelModel?
|
public var topRightLabel: LabelModel?
|
||||||
public var bottomLeftLabel: LabelModel?
|
public var bottomLeftLabel: LabelModel?
|
||||||
public var bottomRightLabel: LabelModel?
|
public var bottomRightLabel: LabelModel?
|
||||||
public var molecule: MoleculeModelProtocol
|
public var molecule: MoleculeModelProtocol?
|
||||||
|
|
||||||
init(with molecule: MoleculeModelProtocol) {
|
init(with molecule: MoleculeModelProtocol?) {
|
||||||
self.molecule = molecule
|
self.molecule = molecule
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ public class CornerLabelsModel: MoleculeModelProtocol {
|
|||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
molecule = try typeContainer.decodeMolecule(codingKey: .molecule)
|
molecule = try typeContainer.decodeMoleculeIfPresent(codingKey: .molecule)
|
||||||
topLeftLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .topLeftLabel)
|
topLeftLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .topLeftLabel)
|
||||||
topRightLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .topRightLabel)
|
topRightLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .topRightLabel)
|
||||||
bottomLeftLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .bottomLeftLabel)
|
bottomLeftLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .bottomLeftLabel)
|
||||||
|
|||||||
@ -9,9 +9,8 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
@objcMembers public class HeadLineBodyCaretLinkImage: Container {
|
@objcMembers public class HeadLineBodyCaretLinkImage: Container {
|
||||||
let headlineBody = HeadlineBody(frame: .zero)
|
let headlineBody = HeadlineBody(frame: .zero)
|
||||||
let caretButton = CaretButton(frame: .zero)
|
let caretButton = CaretLink(frame: .zero)
|
||||||
let backgroundImageView = MFLoadImageView(pinnedEdges: .all)
|
let backgroundImageView = MFLoadImageView(pinnedEdges: .all)
|
||||||
var spaceBetweenConstant: CGFloat = 104.0
|
|
||||||
let maxWidth: CGFloat = 350.0
|
let maxWidth: CGFloat = 350.0
|
||||||
static let heightConstant: CGFloat = 320.0
|
static let heightConstant: CGFloat = 320.0
|
||||||
var heightConstraint: NSLayoutConstraint?
|
var heightConstraint: NSLayoutConstraint?
|
||||||
@ -44,17 +43,17 @@ import Foundation
|
|||||||
headlineBody.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true
|
headlineBody.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true
|
||||||
headlineBody.topAnchor.constraint(equalTo: container.topAnchor, constant: 0).isActive = true
|
headlineBody.topAnchor.constraint(equalTo: container.topAnchor, constant: 0).isActive = true
|
||||||
|
|
||||||
let headLineBodyWidth = headlineBody.widthAnchor.constraint(equalTo: container.widthAnchor, multiplier: 0.85)
|
headlineBody.widthAnchor.constraint(equalTo: container.widthAnchor, multiplier: 0.67).isActive = true
|
||||||
headLineBodyWidth.priority = .defaultHigh
|
let headLineBodyWidth = headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: maxWidth)
|
||||||
|
headLineBodyWidth.priority = UILayoutPriority(250)
|
||||||
headLineBodyWidth.isActive = true
|
headLineBodyWidth.isActive = true
|
||||||
headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: maxWidth).isActive = true
|
|
||||||
|
|
||||||
//Caret view
|
//Caret view
|
||||||
caretButton.translatesAutoresizingMaskIntoConstraints = false
|
caretButton.translatesAutoresizingMaskIntoConstraints = false
|
||||||
caretButton.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true
|
caretButton.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true
|
||||||
container.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor, constant: 0).isActive = true
|
container.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor, constant: 0).isActive = true
|
||||||
|
|
||||||
caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant).isActive = true
|
caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: PaddingTwo).isActive = true
|
||||||
|
|
||||||
//Background image view
|
//Background image view
|
||||||
backgroundImageView.translatesAutoresizingMaskIntoConstraints = false
|
backgroundImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
@ -67,13 +66,6 @@ import Foundation
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
backgroundImageView.setWithJSON(json?.optionalDictionaryForKey("image"), delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
headlineBody.setWithJSON(json?.optionalDictionaryForKey("headlineBody"), delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
caretButton.setWithJSON(json?.optionalDictionaryForKey("caretLink"), delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
headlineBody.reset()
|
headlineBody.reset()
|
||||||
|
|||||||
@ -24,9 +24,8 @@ open class HeadlineBody: View {
|
|||||||
|
|
||||||
// MARK: - Styling
|
// MARK: - Styling
|
||||||
func style(with styleString: String?) {
|
func style(with styleString: String?) {
|
||||||
guard let styleString = styleString else {
|
guard let styleString = styleString else { return }
|
||||||
return
|
|
||||||
}
|
|
||||||
switch styleString {
|
switch styleString {
|
||||||
case "header":
|
case "header":
|
||||||
stylePageHeader()
|
stylePageHeader()
|
||||||
@ -72,10 +71,9 @@ open class HeadlineBody: View {
|
|||||||
|
|
||||||
open override func setupView() {
|
open override func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
guard subviews.count == 0 else {
|
|
||||||
return
|
guard subviews.isEmpty else { return }
|
||||||
}
|
|
||||||
translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
clipsToBounds = true
|
clipsToBounds = true
|
||||||
|
|
||||||
@ -86,9 +84,9 @@ open class HeadlineBody: View {
|
|||||||
view.addSubview(headlineLabel)
|
view.addSubview(headlineLabel)
|
||||||
view.addSubview(messageLabel)
|
view.addSubview(messageLabel)
|
||||||
|
|
||||||
headlineLabel.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical)
|
headlineLabel.setContentHuggingPriority(.required, for: .vertical)
|
||||||
messageLabel.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical)
|
messageLabel.setContentHuggingPriority(.required, for: .vertical)
|
||||||
view.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical)
|
view.setContentHuggingPriority(.required, for: .vertical)
|
||||||
|
|
||||||
headlineLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
|
headlineLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
|
||||||
|
|
||||||
@ -110,7 +108,10 @@ open class HeadlineBody: View {
|
|||||||
view.bottomAnchor.constraint(equalTo: messageLabel.bottomAnchor, constant: 0).isActive = true
|
view.bottomAnchor.constraint(equalTo: messageLabel.bottomAnchor, constant: 0).isActive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - Constraining
|
// MARK: - Constraining
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public func setSpacing() {
|
public func setSpacing() {
|
||||||
if headlineLabel.hasText && messageLabel.hasText {
|
if headlineLabel.hasText && messageLabel.hasText {
|
||||||
spaceBetweenLabels?.constant = spaceBetweenLabelsConstant
|
spaceBetweenLabels?.constant = spaceBetweenLabelsConstant
|
||||||
@ -119,25 +120,29 @@ open class HeadlineBody: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK:- ModelMoleculeViewProtocol
|
//--------------------------------------------------
|
||||||
|
// MARK: - ModelMoleculeViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
return 58
|
return 58
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
|
||||||
super.setWithModel(model, delegateObject, additionalData)
|
super.setWithModel(model, delegateObject, additionalData)
|
||||||
guard let headlineBodyModel = model as? HeadlineBodyModel else {
|
|
||||||
return
|
guard let headlineBodyModel = model as? HeadlineBodyModel else { return }
|
||||||
}
|
|
||||||
|
|
||||||
style(with: headlineBodyModel.style)
|
style(with: headlineBodyModel.style)
|
||||||
|
|
||||||
headlineLabel.setWithModel(headlineBodyModel.headline, delegateObject, additionalData)
|
headlineLabel.setWithModel(headlineBodyModel.headline, delegateObject, additionalData)
|
||||||
messageLabel.setWithModel(headlineBodyModel.body, delegateObject, additionalData)
|
messageLabel.setWithModel(headlineBodyModel.body, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
|
|
||||||
@ -159,4 +164,3 @@ open class HeadlineBody: View {
|
|||||||
return 58
|
return 58
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,4 +20,3 @@ import Foundation
|
|||||||
self.headline = headline
|
self.headline = headline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,8 +33,9 @@ open class Stack<T>: Container where T: StackModelProtocol {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Adds the views
|
// Adds the views
|
||||||
|
let totalSpace = getTotalSpace()
|
||||||
for (index, view) in stackItems.enumerated() {
|
for (index, view) in stackItems.enumerated() {
|
||||||
addView(view, stackModel.molecules[index], percentModifier: getPercentModifier(), lastItem: lastItemIndex == index)
|
addView(view, stackModel.molecules[index], totalSpacing: totalSpace, lastItem: lastItemIndex == index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,14 +174,12 @@ open class Stack<T>: Container where T: StackModelProtocol {
|
|||||||
|
|
||||||
// MARK: - Adding to stack
|
// MARK: - Adding to stack
|
||||||
/// Gets the percent modifier. This value is used to help properly calculate percent for stack items when spacing is involved.
|
/// Gets the percent modifier. This value is used to help properly calculate percent for stack items when spacing is involved.
|
||||||
private func getPercentModifier() -> CGFloat {
|
private func getTotalSpace() -> CGFloat {
|
||||||
guard let stackModel = stackModel else { return 0.0 }
|
guard let stackModel = stackModel else { return 0.0 }
|
||||||
var totalSpace: CGFloat = 0.0
|
var totalSpace: CGFloat = 0.0
|
||||||
var totalViews = 0
|
|
||||||
var firstMoleculeFound = false
|
var firstMoleculeFound = false
|
||||||
for stackItemModel in stackModel.molecules {
|
for stackItemModel in stackModel.molecules {
|
||||||
guard !stackItemModel.gone else { continue }
|
guard !stackItemModel.gone else { continue }
|
||||||
totalViews += 1
|
|
||||||
let spacing = stackItemModel.spacing ?? stackModel.spacing
|
let spacing = stackItemModel.spacing ?? stackModel.spacing
|
||||||
if firstMoleculeFound {
|
if firstMoleculeFound {
|
||||||
totalSpace += spacing
|
totalSpace += spacing
|
||||||
@ -189,11 +188,11 @@ open class Stack<T>: Container where T: StackModelProtocol {
|
|||||||
totalSpace += (stackModel.useStackSpacingBeforeFirstItem ? spacing : stackItemModel.spacing ?? 0)
|
totalSpace += (stackModel.useStackSpacingBeforeFirstItem ? spacing : stackItemModel.spacing ?? 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (totalViews > 0 ? -(totalSpace / CGFloat(totalViews)) : 0)
|
return totalSpace
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds the stack item view
|
/// Adds the stack item view
|
||||||
private func addView(_ view: UIView,_ model: StackItemModelProtocol, percentModifier: CGFloat, lastItem: Bool) {
|
private func addView(_ view: UIView,_ model: StackItemModelProtocol, totalSpacing: CGFloat, lastItem: Bool) {
|
||||||
guard let stackModel = self.stackModel else { return }
|
guard let stackModel = self.stackModel else { return }
|
||||||
guard !model.gone else {
|
guard !model.gone else {
|
||||||
// Gone views do not show
|
// Gone views do not show
|
||||||
@ -223,7 +222,9 @@ open class Stack<T>: Container where T: StackModelProtocol {
|
|||||||
pinView(view, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: 0)
|
pinView(view, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: 0)
|
||||||
pinView(contentView, toView: view, attribute: .trailing, relation: .equal, priority: .required, constant: 0)
|
pinView(contentView, toView: view, attribute: .trailing, relation: .equal, priority: .required, constant: 0)
|
||||||
if let percent = model.percent {
|
if let percent = model.percent {
|
||||||
view.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: CGFloat(percent)/100.0, constant: percentModifier).isActive = true
|
let multiplier = CGFloat(percent)/100.0
|
||||||
|
let constant = multiplier * totalSpacing
|
||||||
|
view.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: multiplier, constant: -constant).isActive = true
|
||||||
}
|
}
|
||||||
if lastItem {
|
if lastItem {
|
||||||
pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0)
|
pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0)
|
||||||
@ -240,7 +241,9 @@ open class Stack<T>: Container where T: StackModelProtocol {
|
|||||||
pinView(view, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: 0)
|
pinView(view, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: 0)
|
||||||
pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0)
|
pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0)
|
||||||
if let percent = model.percent {
|
if let percent = model.percent {
|
||||||
view.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: CGFloat(percent)/100.0, constant: percentModifier).isActive = true
|
let multiplier = CGFloat(percent)/100.0
|
||||||
|
let constant = multiplier * totalSpacing
|
||||||
|
view.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: multiplier, constant: -constant).isActive = true
|
||||||
}
|
}
|
||||||
if lastItem {
|
if lastItem {
|
||||||
pinView(contentView, toView: view, attribute: .right, relation: .equal, priority: .required, constant: 0)
|
pinView(contentView, toView: view, attribute: .right, relation: .equal, priority: .required, constant: 0)
|
||||||
|
|||||||
@ -30,7 +30,7 @@ import Foundation
|
|||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TwoButtonView.self, viewModelClass: TwoButtonViewModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TwoButtonView.self, viewModelClass: TwoButtonViewModel.self)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Link.self, viewModelClass: LinkModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Link.self, viewModelClass: LinkModel.self)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretButton.self, viewModelClass: CaretLinkModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretLink.self, viewModelClass: CaretLinkModel.self)
|
||||||
|
|
||||||
// Entry Field
|
// Entry Field
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TextEntryField.self, viewModelClass: TextEntryFieldModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TextEntryField.self, viewModelClass: TextEntryFieldModel.self)
|
||||||
|
|||||||
@ -9,52 +9,67 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol {
|
open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Stored Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)]?
|
public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)]?
|
||||||
|
|
||||||
var observer: NSKeyValueObservation?
|
var observer: NSKeyValueObservation?
|
||||||
|
|
||||||
public var templateModel: ListPageTemplateModel?
|
public var templateModel: ListPageTemplateModel?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Computed Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
@objc public override func parsePageJSON() throws {
|
@objc public override func parsePageJSON() throws {
|
||||||
try parseTemplateJSON()
|
try parseTemplateJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override var loadObject: MVMCoreLoadObject? {
|
open override var loadObject: MVMCoreLoadObject? {
|
||||||
didSet {
|
didSet {
|
||||||
if loadObject != oldValue {
|
guard loadObject != oldValue else { return }
|
||||||
updateRequiredModules()
|
|
||||||
observer?.invalidate()
|
updateRequiredModules()
|
||||||
if let newObject = loadObject {
|
observer?.invalidate()
|
||||||
observer = newObject.observe(\MVMCoreLoadObject.pageJSON, options: [.old, .new]) { [weak self] (object, change) in
|
if let newObject = loadObject {
|
||||||
self?.updateRequiredModules()
|
observer = newObject.observe(\MVMCoreLoadObject.pageJSON, options: [.old, .new]) { [weak self] object, change in
|
||||||
}
|
self?.updateRequiredModules()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Methods
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func viewForTop() -> UIView {
|
open override func viewForTop() -> UIView {
|
||||||
guard let headerModel = templateModel?.header,
|
guard let headerModel = templateModel?.header,
|
||||||
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(headerModel, delegateObject() as? MVMCoreUIDelegateObject, false) else {
|
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(headerModel, delegateObject() as? MVMCoreUIDelegateObject, false)
|
||||||
return super.viewForTop()
|
else { return super.viewForTop() }
|
||||||
}
|
|
||||||
|
|
||||||
// Temporary, Default the horizontal padding
|
// Temporary, Default the horizontal padding
|
||||||
if var container = templateModel?.header as? ContainerModelProtocol, container.useHorizontalMargins == nil {
|
if var container = templateModel?.header as? ContainerModelProtocol, container.useHorizontalMargins == nil {
|
||||||
container.useHorizontalMargins = true
|
container.useHorizontalMargins = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return molecule
|
return molecule
|
||||||
}
|
}
|
||||||
|
|
||||||
override open func viewForBottom() -> UIView {
|
override open func viewForBottom() -> UIView {
|
||||||
guard let footerModel = templateModel?.footer,
|
guard let footerModel = templateModel?.footer,
|
||||||
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(footerModel, delegateObject() as? MVMCoreUIDelegateObject, false) else {
|
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(footerModel, delegateObject() as? MVMCoreUIDelegateObject, false)
|
||||||
return super.viewForBottom()
|
else { return super.viewForBottom() }
|
||||||
}
|
|
||||||
return molecule
|
return molecule
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
|
open override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
|
||||||
|
|
||||||
guard super.shouldFinishProcessingLoad(loadObject, error: error) else { return false }
|
guard super.shouldFinishProcessingLoad(loadObject, error: error) else { return false }
|
||||||
|
|
||||||
// This template requires atleast one of the three layers.
|
// This template requires atleast one of the three layers.
|
||||||
if templateModel?.header == nil,
|
if templateModel?.header == nil,
|
||||||
templateModel?.molecules?.count ?? 0 == 0,
|
templateModel?.molecules?.count ?? 0 == 0,
|
||||||
@ -72,7 +87,10 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
registerWithTable()
|
registerWithTable()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - table
|
//--------------------------------------------------
|
||||||
|
// MARK: - Table View
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func registerWithTable() {
|
open override func registerWithTable() {
|
||||||
super.registerWithTable()
|
super.registerWithTable()
|
||||||
guard let moleculesInfo = moleculesInfo else { return }
|
guard let moleculesInfo = moleculesInfo else { return }
|
||||||
@ -84,9 +102,9 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
|
|
||||||
open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
|
open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
|
||||||
guard let moleculeInfo = moleculesInfo?[indexPath.row],
|
guard let moleculeInfo = moleculesInfo?[indexPath.row],
|
||||||
let estimatedHeight = (moleculeInfo.class as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(forRow: moleculeInfo.molecule, delegateObject: delegateObject() as? MVMCoreUIDelegateObject) else {
|
let estimatedHeight = (moleculeInfo.class as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(forRow: moleculeInfo.molecule, delegateObject: delegateObject() as? MVMCoreUIDelegateObject)
|
||||||
return 0
|
else { return 0 }
|
||||||
}
|
|
||||||
return estimatedHeight
|
return estimatedHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,18 +113,22 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
|
|
||||||
guard let moleculeInfo = moleculesInfo?[indexPath.row],
|
guard let moleculeInfo = moleculesInfo?[indexPath.row],
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier) else {
|
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier)
|
||||||
return UITableViewCell()
|
else { return UITableViewCell() }
|
||||||
}
|
|
||||||
let delegate = delegateObject() as? MVMCoreUIDelegateObject
|
let delegate = delegateObject() as? MVMCoreUIDelegateObject
|
||||||
let moleculeCell = cell as? MVMCoreUIMoleculeViewProtocol
|
let moleculeCell = cell as? MVMCoreUIMoleculeViewProtocol
|
||||||
moleculeCell?.reset?()
|
moleculeCell?.reset?()
|
||||||
|
|
||||||
if let protocolCell = cell as? MoleculeListCellProtocol {
|
if let protocolCell = cell as? MoleculeListCellProtocol {
|
||||||
protocolCell.setLines(with: templateModel?.line, delegateObject: delegate, additionalData: nil, indexPath: indexPath)
|
protocolCell.setLines(with: templateModel?.line, delegateObject: delegate, additionalData: nil, indexPath: indexPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
(moleculeCell as? ModelMoleculeViewProtocol)?.setWithModel(moleculeInfo.molecule, delegate, nil)
|
(moleculeCell as? ModelMoleculeViewProtocol)?.setWithModel(moleculeInfo.molecule, delegate, nil)
|
||||||
moleculeCell?.updateView(tableView.bounds.width)
|
moleculeCell?.updateView(tableView.bounds.width)
|
||||||
|
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,16 +140,18 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
|
||||||
if let cell = tableView.cellForRow(at: indexPath) as? MoleculeListCellProtocol {
|
if let cell = tableView.cellForRow(at: indexPath) as? MoleculeListCellProtocol {
|
||||||
cell.didSelectCell(at: indexPath, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
|
cell.didSelectCell(at: indexPath, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - cache handling
|
//--------------------------------------------------
|
||||||
|
// MARK: - Cache Handling
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func pageTypesToListenFor() -> [Any]? {
|
open override func pageTypesToListenFor() -> [Any]? {
|
||||||
guard let pageType = self.pageType else {
|
guard let pageType = self.pageType else { return super.pageTypesToListenFor() }
|
||||||
return super.pageTypesToListenFor()
|
|
||||||
}
|
|
||||||
return [pageType]
|
return [pageType]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,8 +159,12 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
return loadObject?.requestParameters?.modules
|
return loadObject?.requestParameters?.modules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - MoleculeDelegateProtocol
|
// MARK: - MoleculeDelegateProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) {
|
open override func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) {
|
||||||
|
|
||||||
if let tableView = tableView {
|
if let tableView = tableView {
|
||||||
let point = molecule.convert(molecule.bounds.origin, to: tableView)
|
let point = molecule.convert(molecule.bounds.origin, to: tableView)
|
||||||
if let indexPath = tableView.indexPathForRow(at: point), tableView.indexPathsForVisibleRows?.contains(indexPath) ?? false {
|
if let indexPath = tableView.indexPathForRow(at: point), tableView.indexPathsForVisibleRows?.contains(indexPath) ?? false {
|
||||||
@ -159,6 +187,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
guard let indexPath = self.tableView?.indexPath(for: sender) else { return }
|
guard let indexPath = self.tableView?.indexPath(for: sender) else { return }
|
||||||
var indexPaths: [IndexPath] = []
|
var indexPaths: [IndexPath] = []
|
||||||
|
|
||||||
for molecule in tmpMolecules {
|
for molecule in tmpMolecules {
|
||||||
if let info = self.getMoleculeInfo(with: molecule) {
|
if let info = self.getMoleculeInfo(with: molecule) {
|
||||||
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
|
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
|
||||||
@ -167,6 +196,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
indexPaths.append(IndexPath(row: index, section: 0))
|
indexPaths.append(IndexPath(row: index, section: 0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tableView?.insertRows(at: indexPaths, with: animation)
|
self.tableView?.insertRows(at: indexPaths, with: animation)
|
||||||
self.updateViewConstraints()
|
self.updateViewConstraints()
|
||||||
self.view.layoutIfNeeded()
|
self.view.layoutIfNeeded()
|
||||||
@ -184,25 +214,29 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
var indexPaths: [IndexPath] = []
|
var indexPaths: [IndexPath] = []
|
||||||
|
|
||||||
//TODO: cehck for molecule protocola eqality
|
//TODO: cehck for molecule protocola eqality
|
||||||
|
|
||||||
for molecule in tmpMolecules {
|
for molecule in tmpMolecules {
|
||||||
if let removeIndex = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in
|
if let removeIndex = moleculesInfo?.firstIndex(where: { molecule.toJSON() == $0.molecule.toJSON() }) {
|
||||||
return molecule.toJSONString() == moleculeInfo.molecule.toJSONString()
|
|
||||||
}) {
|
|
||||||
moleculesInfo?.remove(at: removeIndex)
|
moleculesInfo?.remove(at: removeIndex)
|
||||||
indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0))
|
indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.tableView?.deleteRows(at: indexPaths, with: animation)
|
|
||||||
self.updateViewConstraints()
|
tableView?.deleteRows(at: indexPaths, with: animation)
|
||||||
self.view.layoutIfNeeded()
|
updateViewConstraints()
|
||||||
|
view.layoutIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func addMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
public func addMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||||
|
|
||||||
// This dispatch is needed to fix a race condition that can occur if this function is called during the table setup.
|
// This dispatch is needed to fix a race condition that can occur if this function is called during the table setup.
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
guard let indexPath = self.tableView?.indexPath(for: sender) else { return }
|
guard let indexPath = self.tableView?.indexPath(for: sender) else { return }
|
||||||
var indexPaths: [IndexPath] = []
|
var indexPaths: [IndexPath] = []
|
||||||
|
|
||||||
for molecule in molecules {
|
for molecule in molecules {
|
||||||
if let info = self.getMoleculeInfo(with: molecule) {
|
if let info = self.getMoleculeInfo(with: molecule) {
|
||||||
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
|
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
|
||||||
@ -211,6 +245,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
indexPaths.append(IndexPath(row: index, section: 0))
|
indexPaths.append(IndexPath(row: index, section: 0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tableView?.insertRows(at: indexPaths, with: animation)
|
self.tableView?.insertRows(at: indexPaths, with: animation)
|
||||||
self.updateViewConstraints()
|
self.updateViewConstraints()
|
||||||
self.view.layoutIfNeeded()
|
self.view.layoutIfNeeded()
|
||||||
@ -218,35 +253,42 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func removeMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
public func removeMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||||
|
|
||||||
var indexPaths: [IndexPath] = []
|
var indexPaths: [IndexPath] = []
|
||||||
//TODO: cehck for molecule protocola eqality
|
//TODO: cehck for molecule protocola eqality
|
||||||
|
|
||||||
for molecule in molecules {
|
for molecule in molecules {
|
||||||
if let removeIndex = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in
|
if let removeIndex = moleculesInfo?.firstIndex(where: { molecule.toJSON() == $0.molecule.toJSON() }) {
|
||||||
return molecule.toJSONString() == moleculeInfo.molecule.toJSONString()
|
|
||||||
}) {
|
|
||||||
moleculesInfo?.remove(at: removeIndex)
|
moleculesInfo?.remove(at: removeIndex)
|
||||||
indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0))
|
indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.tableView?.deleteRows(at: indexPaths, with: animation)
|
|
||||||
self.updateViewConstraints()
|
tableView?.deleteRows(at: indexPaths, with: animation)
|
||||||
self.view.layoutIfNeeded()
|
updateViewConstraints()
|
||||||
|
view.layoutIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
// MARK: - Convenience
|
// MARK: - Convenience
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
/// Returns the (identifier, class) of the molecule for the given map.
|
/// Returns the (identifier, class) of the molecule for the given map.
|
||||||
func getMoleculeInfo(with listItem: ListItemModelProtocol?) -> (identifier: String, class: AnyClass, molecule: ListItemModelProtocol)? {
|
func getMoleculeInfo(with listItem: ListItemModelProtocol?) -> (identifier: String, class: AnyClass, molecule: ListItemModelProtocol)? {
|
||||||
|
|
||||||
guard let listItem = listItem,
|
guard let listItem = listItem,
|
||||||
let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(listItem),
|
let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(listItem),
|
||||||
let moleculeName = (moleculeClass as? ModelMoleculeViewProtocol.Type)?.nameForReuse(listItem, delegateObject() as? MVMCoreUIDelegateObject) ?? listItem.moleculeName else {
|
let moleculeName = (moleculeClass as? ModelMoleculeViewProtocol.Type)?.nameForReuse(listItem, delegateObject() as? MVMCoreUIDelegateObject) ?? listItem.moleculeName
|
||||||
return nil
|
else { return nil }
|
||||||
}
|
|
||||||
return (moleculeName, moleculeClass, listItem)
|
return (moleculeName, moleculeClass, listItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets up the molecule list and ensures no errors loading all content.
|
/// Sets up the molecule list and ensures no errors loading all content.
|
||||||
func getMoleculeInfoList() -> [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)]? {
|
func getMoleculeInfoList() -> [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)]? {
|
||||||
|
|
||||||
var moleculeList: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)] = []
|
var moleculeList: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)] = []
|
||||||
|
|
||||||
if let molecules = templateModel?.molecules {
|
if let molecules = templateModel?.molecules {
|
||||||
for molecule in molecules {
|
for molecule in molecules {
|
||||||
if let info = getMoleculeInfo(with: molecule) {
|
if let info = getMoleculeInfo(with: molecule) {
|
||||||
@ -254,6 +296,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return moleculeList.count > 0 ? moleculeList : nil
|
return moleculeList.count > 0 ? moleculeList : nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,15 +314,19 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
|
|
||||||
/// Gets modules required by the loadObject.pageJSON.
|
/// Gets modules required by the loadObject.pageJSON.
|
||||||
open func requiredModules() -> [Any]? {
|
open func requiredModules() -> [Any]? {
|
||||||
|
|
||||||
let modules: NSMutableArray = []
|
let modules: NSMutableArray = []
|
||||||
let delegate = delegateObject() as? MVMCoreUIDelegateObject
|
let delegate = delegateObject() as? MVMCoreUIDelegateObject
|
||||||
|
|
||||||
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate, moduleList: modules, errorList: nil)
|
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate, moduleList: modules, errorList: nil)
|
||||||
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate, moduleList: modules, errorList: nil)
|
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate, moduleList: modules, errorList: nil)
|
||||||
|
|
||||||
if let molecules = loadObject?.pageJSON?.optionalArrayForKey(KeyMolecules) as? [[AnyHashable: Any]] {
|
if let molecules = loadObject?.pageJSON?.optionalArrayForKey(KeyMolecules) as? [[AnyHashable: Any]] {
|
||||||
for molecule in molecules {
|
for molecule in molecules {
|
||||||
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: molecule, delegateObject: delegate, moduleList: modules, errorList: nil)
|
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: molecule, delegateObject: delegate, moduleList: modules, errorList: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return modules as? [Any]
|
return modules as? [Any]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,14 +30,14 @@ import Foundation
|
|||||||
case screenHeading
|
case screenHeading
|
||||||
case header
|
case header
|
||||||
case footer
|
case footer
|
||||||
case moleculeStack
|
case stack
|
||||||
case isAtomicTabs
|
case isAtomicTabs
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
pageType = try typeContainer.decode(String.self, forKey: .pageType)
|
pageType = try typeContainer.decode(String.self, forKey: .pageType)
|
||||||
moleculeStack = try typeContainer.decode(MoleculeStackModel.self, forKey: .moleculeStack)
|
moleculeStack = try typeContainer.decode(MoleculeStackModel.self, forKey: .stack)
|
||||||
screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading)
|
screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading)
|
||||||
isAtomicTabs = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAtomicTabs)
|
isAtomicTabs = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAtomicTabs)
|
||||||
header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header)
|
header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header)
|
||||||
@ -47,7 +47,7 @@ import Foundation
|
|||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(pageType, forKey: .pageType)
|
try container.encode(pageType, forKey: .pageType)
|
||||||
try container.encode(moleculeStack, forKey: .moleculeStack)
|
try container.encode(moleculeStack, forKey: .stack)
|
||||||
try container.encodeIfPresent(screenHeading, forKey: .screenHeading)
|
try container.encodeIfPresent(screenHeading, forKey: .screenHeading)
|
||||||
try container.encodeIfPresent(isAtomicTabs, forKey: .isAtomicTabs)
|
try container.encodeIfPresent(isAtomicTabs, forKey: .isAtomicTabs)
|
||||||
try container.encodeModelIfPresent(header, forKey: .header)
|
try container.encodeModelIfPresent(header, forKey: .header)
|
||||||
|
|||||||
@ -41,7 +41,7 @@ import Foundation
|
|||||||
screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading)
|
screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading)
|
||||||
isAtomicTabs = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAtomicTabs)
|
isAtomicTabs = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAtomicTabs)
|
||||||
header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header)
|
header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header)
|
||||||
header = try typeContainer.decodeMoleculeIfPresent(codingKey: .middle)
|
middle = try typeContainer.decodeMoleculeIfPresent(codingKey: .middle)
|
||||||
footer = try typeContainer.decodeMoleculeIfPresent(codingKey: .footer)
|
footer = try typeContainer.decodeMoleculeIfPresent(codingKey: .footer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user