Merge branch 'feature/coding' of gitlab.verizon.com:BPHV_MIPS/mvm_core_ui into feature/coding
This commit is contained in:
commit
0808d63e24
@ -84,10 +84,12 @@
|
|||||||
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; };
|
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; };
|
||||||
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; };
|
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; };
|
||||||
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B392398524F0067DD0F /* Toggle.swift */; };
|
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B392398524F0067DD0F /* Toggle.swift */; };
|
||||||
0ABD136B237B193A0081388D /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136A237B193A0081388D /* EntryFieldContainer.swift */; };
|
|
||||||
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; };
|
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; };
|
||||||
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; };
|
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; };
|
||||||
|
0ACDF26B23DA0AC2002044B2 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ACDF26A23DA0AC2002044B2 /* EntryFieldContainer.swift */; };
|
||||||
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 */; };
|
||||||
|
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.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 */; };
|
||||||
9445890C2385BCE300DE9FD4 /* ProgressBarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */; };
|
9445890C2385BCE300DE9FD4 /* ProgressBarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */; };
|
||||||
@ -305,6 +307,7 @@
|
|||||||
D2E2A99823D8D63C000B42E6 /* ActionDetailWithImageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E2A99723D8D63C000B42E6 /* ActionDetailWithImageModel.swift */; };
|
D2E2A99823D8D63C000B42E6 /* ActionDetailWithImageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E2A99723D8D63C000B42E6 /* ActionDetailWithImageModel.swift */; };
|
||||||
D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E2A99923D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift */; };
|
D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E2A99923D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift */; };
|
||||||
D2E2A99C23D8D975000B42E6 /* ImageHeadlineBodyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E2A99B23D8D975000B42E6 /* ImageHeadlineBodyModel.swift */; };
|
D2E2A99C23D8D975000B42E6 /* ImageHeadlineBodyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E2A99B23D8D975000B42E6 /* ImageHeadlineBodyModel.swift */; };
|
||||||
|
D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A209CD223A7E2810068F8B0 /* UIStackViewAlignment+Extension.swift */; };
|
||||||
D2FB151B23A2B65B00C20E10 /* MoleculeContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */; };
|
D2FB151B23A2B65B00C20E10 /* MoleculeContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */; };
|
||||||
D2FB151D23A40F1500C20E10 /* MoleculeStackItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FB151C23A40F1500C20E10 /* MoleculeStackItem.swift */; };
|
D2FB151D23A40F1500C20E10 /* MoleculeStackItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FB151C23A40F1500C20E10 /* MoleculeStackItem.swift */; };
|
||||||
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */; };
|
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */; };
|
||||||
@ -384,10 +387,12 @@
|
|||||||
0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = "<group>"; };
|
0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = "<group>"; };
|
||||||
0AA33B33239813C50067DD0F /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = "<group>"; };
|
0AA33B33239813C50067DD0F /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = "<group>"; };
|
||||||
0AA33B392398524F0067DD0F /* Toggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toggle.swift; sourceTree = "<group>"; };
|
0AA33B392398524F0067DD0F /* Toggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toggle.swift; sourceTree = "<group>"; };
|
||||||
0ABD136A237B193A0081388D /* EntryFieldContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = "<group>"; };
|
|
||||||
0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = "<group>"; };
|
0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = "<group>"; };
|
||||||
0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = "<group>"; };
|
0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = "<group>"; };
|
||||||
|
0ACDF26A23DA0AC2002044B2 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = "<group>"; };
|
||||||
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>"; };
|
||||||
|
31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.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>"; };
|
||||||
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>"; };
|
||||||
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = "<group>"; };
|
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = "<group>"; };
|
||||||
@ -697,7 +702,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D29E28DE23D740FC00ACEA85 /* Container */,
|
D29E28DE23D740FC00ACEA85 /* Container */,
|
||||||
0ABD136A237B193A0081388D /* EntryFieldContainer.swift */,
|
0ACDF26A23DA0AC2002044B2 /* EntryFieldContainer.swift */,
|
||||||
014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */,
|
014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */,
|
||||||
D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */,
|
D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */,
|
||||||
);
|
);
|
||||||
@ -1160,7 +1165,9 @@
|
|||||||
D268C711238D6699007F2C1C /* DropDown.swift */,
|
D268C711238D6699007F2C1C /* DropDown.swift */,
|
||||||
DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */,
|
DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */,
|
||||||
94C2D9822386F3E30006CF46 /* Label */,
|
94C2D9822386F3E30006CF46 /* Label */,
|
||||||
|
31BE15CA23D8924C00452370 /* CheckboxModel.swift */,
|
||||||
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */,
|
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */,
|
||||||
|
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */,
|
||||||
0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */,
|
0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */,
|
||||||
01004F2F22721C3800991ECC /* RadioButton.swift */,
|
01004F2F22721C3800991ECC /* RadioButton.swift */,
|
||||||
D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */,
|
D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */,
|
||||||
@ -1491,6 +1498,7 @@
|
|||||||
files = (
|
files = (
|
||||||
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
|
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
|
||||||
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */,
|
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */,
|
||||||
|
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */,
|
||||||
94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */,
|
94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */,
|
||||||
D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */,
|
D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */,
|
||||||
D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */,
|
D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */,
|
||||||
@ -1532,6 +1540,7 @@
|
|||||||
D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */,
|
D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */,
|
||||||
D260106323D0C05000764D80 /* StackItemModel.swift in Sources */,
|
D260106323D0C05000764D80 /* StackItemModel.swift in Sources */,
|
||||||
D2E2A99823D8D63C000B42E6 /* ActionDetailWithImageModel.swift in Sources */,
|
D2E2A99823D8D63C000B42E6 /* ActionDetailWithImageModel.swift in Sources */,
|
||||||
|
D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */,
|
||||||
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */,
|
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */,
|
||||||
0A21DB7F235DECC500C160A2 /* EntryField.swift in Sources */,
|
0A21DB7F235DECC500C160A2 /* EntryField.swift in Sources */,
|
||||||
D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */,
|
D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */,
|
||||||
@ -1577,6 +1586,7 @@
|
|||||||
DBEFFA04225A829700230692 /* Label.swift in Sources */,
|
DBEFFA04225A829700230692 /* Label.swift in Sources */,
|
||||||
D2D6CD4022E78C1A00D701B8 /* Scroller.swift in Sources */,
|
D2D6CD4022E78C1A00D701B8 /* Scroller.swift in Sources */,
|
||||||
01509D952327ED1900EF99AA /* HeadlineBodyTextButtonSwitch.swift in Sources */,
|
01509D952327ED1900EF99AA /* HeadlineBodyTextButtonSwitch.swift in Sources */,
|
||||||
|
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */,
|
||||||
D260105523CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift in Sources */,
|
D260105523CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift in Sources */,
|
||||||
D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */,
|
D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */,
|
||||||
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */,
|
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */,
|
||||||
@ -1614,6 +1624,7 @@
|
|||||||
017BEB7F23676E870024EF95 /* MoleculeObjectMapping.swift in Sources */,
|
017BEB7F23676E870024EF95 /* MoleculeObjectMapping.swift in Sources */,
|
||||||
D274CA332236A78900B01B62 /* FooterView.swift in Sources */,
|
D274CA332236A78900B01B62 /* FooterView.swift in Sources */,
|
||||||
D29DF2BF21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.m in Sources */,
|
D29DF2BF21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.m in Sources */,
|
||||||
|
0ACDF26B23DA0AC2002044B2 /* EntryFieldContainer.swift in Sources */,
|
||||||
014AA72423C501E2006F3E93 /* MoleculeContainerModel.swift in Sources */,
|
014AA72423C501E2006F3E93 /* MoleculeContainerModel.swift in Sources */,
|
||||||
D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */,
|
D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */,
|
||||||
011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */,
|
011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */,
|
||||||
@ -1696,7 +1707,6 @@
|
|||||||
D2B18B922361E65A00A9AEDC /* CoreUIObject.swift in Sources */,
|
D2B18B922361E65A00A9AEDC /* CoreUIObject.swift in Sources */,
|
||||||
D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */,
|
D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */,
|
||||||
014AA72E23C5059B006F3E93 /* StackCenteredPageTemplateModel.swift in Sources */,
|
014AA72E23C5059B006F3E93 /* StackCenteredPageTemplateModel.swift in Sources */,
|
||||||
0ABD136B237B193A0081388D /* EntryFieldContainer.swift in Sources */,
|
|
||||||
D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */,
|
D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */,
|
||||||
D260105923D0A92900764D80 /* ContainerProtocol.swift in Sources */,
|
D260105923D0A92900764D80 /* ContainerProtocol.swift in Sources */,
|
||||||
C695A69423C9909000BFB94E /* DoughnutChartModel.swift in Sources */,
|
C695A69423C9909000BFB94E /* DoughnutChartModel.swift in Sources */,
|
||||||
|
|||||||
@ -76,6 +76,27 @@ import MVMCore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open override var isEnabled: Bool {
|
||||||
|
didSet {
|
||||||
|
|
||||||
|
isUserInteractionEnabled = isEnabled
|
||||||
|
|
||||||
|
if isEnabled {
|
||||||
|
layer.borderColor = borderColor.cgColor
|
||||||
|
backgroundColor = isSelected ? checkedBackgroundColor : unCheckedBackgroundColor
|
||||||
|
setShapeLayerStrokeColor(checkColor)
|
||||||
|
} else {
|
||||||
|
layer.borderColor = disabledBorderColor.cgColor
|
||||||
|
backgroundColor = disabledBackgroundColor
|
||||||
|
setShapeLayerStrokeColor(disabledCheckColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var disabledBackgroundColor: UIColor = .clear
|
||||||
|
public var disabledBorderColor: UIColor = .mvmCoolGray3
|
||||||
|
public var disabledCheckColor: UIColor = .mvmCoolGray3
|
||||||
|
|
||||||
/// Color of the check mark.
|
/// Color of the check mark.
|
||||||
public var checkColor: UIColor = .black {
|
public var checkColor: UIColor = .black {
|
||||||
didSet {
|
didSet {
|
||||||
@ -107,7 +128,6 @@ import MVMCore
|
|||||||
if !updateSelectionOnly {
|
if !updateSelectionOnly {
|
||||||
layoutIfNeeded()
|
layoutIfNeeded()
|
||||||
shapeLayer?.removeAllAnimations()
|
shapeLayer?.removeAllAnimations()
|
||||||
|
|
||||||
updateCheckboxUI(isSelected: isSelected, isAnimated: isAnimated)
|
updateCheckboxUI(isSelected: isSelected, isAnimated: isAnimated)
|
||||||
FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol)
|
FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol)
|
||||||
updateAccessibilityLabel()
|
updateAccessibilityLabel()
|
||||||
@ -154,16 +174,12 @@ import MVMCore
|
|||||||
|
|
||||||
public convenience init(isChecked: Bool) {
|
public convenience init(isChecked: Bool) {
|
||||||
self.init(frame: .zero)
|
self.init(frame: .zero)
|
||||||
updateSelectionOnly = true
|
checkAndBypassAnimations(selected: isChecked)
|
||||||
isSelected = isChecked
|
|
||||||
updateSelectionOnly = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public convenience init(checkedBackgroundColor: UIColor, unCheckedBackgroundColor: UIColor, isChecked: Bool = false) {
|
public convenience init(checkedBackgroundColor: UIColor, unCheckedBackgroundColor: UIColor, isChecked: Bool = false) {
|
||||||
self.init(frame: .zero)
|
self.init(frame: .zero)
|
||||||
updateSelectionOnly = true
|
checkAndBypassAnimations(selected: isChecked)
|
||||||
isSelected = isChecked
|
|
||||||
updateSelectionOnly = false
|
|
||||||
self.checkedBackgroundColor = checkedBackgroundColor
|
self.checkedBackgroundColor = checkedBackgroundColor
|
||||||
self.unCheckedBackgroundColor = unCheckedBackgroundColor
|
self.unCheckedBackgroundColor = unCheckedBackgroundColor
|
||||||
}
|
}
|
||||||
@ -177,8 +193,6 @@ import MVMCore
|
|||||||
|
|
||||||
drawShapeLayer()
|
drawShapeLayer()
|
||||||
layer.cornerRadius = isRound ? cornerRadiusValue : 0
|
layer.cornerRadius = isRound ? cornerRadiusValue : 0
|
||||||
layer.borderWidth = borderWidth
|
|
||||||
layer.borderColor = borderColor.cgColor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func setupView() {
|
open override func setupView() {
|
||||||
@ -228,7 +242,7 @@ import MVMCore
|
|||||||
self.shapeLayer = shapeLayer
|
self.shapeLayer = shapeLayer
|
||||||
shapeLayer.frame = bounds
|
shapeLayer.frame = bounds
|
||||||
layer.addSublayer(shapeLayer)
|
layer.addSublayer(shapeLayer)
|
||||||
shapeLayer.strokeColor = checkColor.cgColor
|
shapeLayer.strokeColor = isEnabled ? checkColor.cgColor : disabledCheckColor.cgColor
|
||||||
shapeLayer.fillColor = UIColor.clear.cgColor
|
shapeLayer.fillColor = UIColor.clear.cgColor
|
||||||
shapeLayer.path = checkMarkPath()
|
shapeLayer.path = checkMarkPath()
|
||||||
shapeLayer.lineJoin = .miter
|
shapeLayer.lineJoin = .miter
|
||||||
@ -268,9 +282,7 @@ import MVMCore
|
|||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
|
||||||
self.updateSelectionOnly = true
|
self.checkAndBypassAnimations(selected: selected)
|
||||||
self.isSelected = selected
|
|
||||||
self.updateSelectionOnly = false
|
|
||||||
self.drawShapeLayer()
|
self.drawShapeLayer()
|
||||||
self.shapeLayer?.removeAllAnimations()
|
self.shapeLayer?.removeAllAnimations()
|
||||||
self.updateCheckboxUI(isSelected: selected, isAnimated: animated)
|
self.updateCheckboxUI(isSelected: selected, isAnimated: animated)
|
||||||
@ -313,23 +325,6 @@ import MVMCore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isEnabled(_ enabled: Bool) {
|
|
||||||
|
|
||||||
isUserInteractionEnabled = enabled
|
|
||||||
|
|
||||||
if enabled {
|
|
||||||
layer.borderColor = borderColor.cgColor
|
|
||||||
backgroundColor = isSelected ? checkedBackgroundColor : unCheckedBackgroundColor
|
|
||||||
alpha = 1.0
|
|
||||||
setShapeLayerStrokeColor(checkColor)
|
|
||||||
} else {
|
|
||||||
layer.borderColor = UIColor.mfSilver().cgColor
|
|
||||||
backgroundColor = .clear
|
|
||||||
alpha = DisableOppacity
|
|
||||||
setShapeLayerStrokeColor(UIColor.mfSilver())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func setShapeLayerStrokeColor(_ color: UIColor) {
|
private func setShapeLayerStrokeColor(_ color: UIColor) {
|
||||||
|
|
||||||
if let shapeLayer = shapeLayer {
|
if let shapeLayer = shapeLayer {
|
||||||
@ -345,13 +340,19 @@ import MVMCore
|
|||||||
widthConstraint?.isActive = isActive
|
widthConstraint?.isActive = isActive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func checkAndBypassAnimations(selected: Bool) {
|
||||||
|
updateSelectionOnly = true
|
||||||
|
isSelected = selected
|
||||||
|
updateSelectionOnly = false
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - UITouch
|
// MARK: - UITouch
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
|
|
||||||
sendActions(for: .touchUpInside)
|
sendActions(for: .touchUpInside)
|
||||||
}
|
}
|
||||||
|
|
||||||
override open func accessibilityActivate() -> Bool {
|
override open func accessibilityActivate() -> Bool {
|
||||||
@ -370,7 +371,7 @@ import MVMCore
|
|||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
|
|
||||||
isEnabled(true)
|
isEnabled = true
|
||||||
shapeLayer?.removeAllAnimations()
|
shapeLayer?.removeAllAnimations()
|
||||||
shapeLayer?.removeFromSuperlayer()
|
shapeLayer?.removeFromSuperlayer()
|
||||||
shapeLayer = nil
|
shapeLayer = nil
|
||||||
@ -379,9 +380,7 @@ import MVMCore
|
|||||||
borderWidth = 1.0
|
borderWidth = 1.0
|
||||||
checkColor = .black
|
checkColor = .black
|
||||||
checkWidth = 2.0
|
checkWidth = 2.0
|
||||||
updateSelectionOnly = true
|
checkAndBypassAnimations(selected: false)
|
||||||
isSelected = false
|
|
||||||
updateSelectionOnly = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open func setAsMolecule() {
|
open func setAsMolecule() {
|
||||||
@ -424,16 +423,14 @@ import MVMCore
|
|||||||
layer.borderWidth = borderWidth
|
layer.borderWidth = borderWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
if let isChecked = dictionary["isChecked"] as? Bool, isChecked {
|
|
||||||
updateSelectionOnly = true
|
|
||||||
isSelected = isChecked
|
|
||||||
updateSelectionOnly = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if let checkColorHex = dictionary["checkColor"] as? String {
|
if let checkColorHex = dictionary["checkColor"] as? String {
|
||||||
checkColor = UIColor.mfGet(forHex: checkColorHex)
|
checkColor = UIColor.mfGet(forHex: checkColorHex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let isChecked = dictionary["isChecked"] as? Bool, isChecked {
|
||||||
|
checkAndBypassAnimations(selected: isChecked)
|
||||||
|
}
|
||||||
|
|
||||||
if let unCheckedBackgroundColorHex = dictionary["unCheckedBackgroundColor"] as? String {
|
if let unCheckedBackgroundColorHex = dictionary["unCheckedBackgroundColor"] as? String {
|
||||||
unCheckedBackgroundColor = UIColor.mfGet(forHex: unCheckedBackgroundColorHex)
|
unCheckedBackgroundColor = UIColor.mfGet(forHex: unCheckedBackgroundColorHex)
|
||||||
}
|
}
|
||||||
@ -451,13 +448,57 @@ import MVMCore
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let enabled = dictionary["isEnabled"] as? Bool {
|
if let enabled = dictionary["isEnabled"] as? Bool {
|
||||||
isEnabled(enabled)
|
isEnabled = enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
if let actionMap = dictionary.optionalDictionaryForKey("action") {
|
if let actionMap = dictionary.optionalDictionaryForKey("action") {
|
||||||
actionBlock = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) }
|
actionBlock = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.setWithModel(model, delegateObject, additionalData)
|
||||||
|
|
||||||
|
guard let model = model as? CheckboxModel else { return }
|
||||||
|
|
||||||
|
self.delegateObject = delegateObject
|
||||||
|
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
|
||||||
|
|
||||||
|
groupName = model.groupName
|
||||||
|
fieldValue = model.value
|
||||||
|
isRequired = model.required
|
||||||
|
|
||||||
|
if let fieldKey = model.fieldKey {
|
||||||
|
self.fieldKey = fieldKey
|
||||||
|
}
|
||||||
|
|
||||||
|
borderColor = model.borderColor.uiColor
|
||||||
|
borderWidth = model.borderWidth
|
||||||
|
|
||||||
|
checkColor = model.checkColor.uiColor
|
||||||
|
unCheckedBackgroundColor = model.unCheckedBackgroundColor.uiColor
|
||||||
|
checkedBackgroundColor = model.checkedBackgroundColor.uiColor
|
||||||
|
disabledCheckColor = model.disabledCheckColor.uiColor
|
||||||
|
disabledBorderColor = model.disabledBorderColor.uiColor
|
||||||
|
disabledBackgroundColor = model.disabledBackgroundColor.uiColor
|
||||||
|
|
||||||
|
isAnimated = model.isAnimated
|
||||||
|
isRound = model.isRound
|
||||||
|
|
||||||
|
if model.isChecked {
|
||||||
|
checkAndBypassAnimations(selected: model.isChecked)
|
||||||
|
}
|
||||||
|
|
||||||
|
isEnabled = model.isEnabled
|
||||||
|
|
||||||
|
if let action = model.action {
|
||||||
|
actionBlock = {
|
||||||
|
if let actionMap = action.toJSON() {
|
||||||
|
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK:- FormValidationProtocol
|
// MARK:- FormValidationProtocol
|
||||||
|
|||||||
24
MVMCoreUI/Atoms/Views/CheckboxLabelModel.swift
Normal file
24
MVMCoreUI/Atoms/Views/CheckboxLabelModel.swift
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// CheckboxWithLabelViewModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Chintakrinda, Arun Kumar (Arun) on 21/01/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public enum CheckboxPosition: String, Codable {
|
||||||
|
case center
|
||||||
|
case top
|
||||||
|
case bottom
|
||||||
|
}
|
||||||
|
|
||||||
|
@objcMembers public class CheckboxLabelModel: MoleculeModelProtocol {
|
||||||
|
public static var identifier: String = "checkboxLabel"
|
||||||
|
public var backgroundColor: Color?
|
||||||
|
|
||||||
|
public var checkboxAlignment: CheckboxPosition?
|
||||||
|
public var checkbox: CheckboxModel
|
||||||
|
public var label: LabelModel
|
||||||
|
}
|
||||||
106
MVMCoreUI/Atoms/Views/CheckboxModel.swift
Normal file
106
MVMCoreUI/Atoms/Views/CheckboxModel.swift
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
//
|
||||||
|
// CheckboxModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Chintakrinda, Arun Kumar (Arun) on 21/01/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers public class CheckboxModel: MoleculeModelProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public static var identifier: String = "checkbox"
|
||||||
|
public var backgroundColor: Color?
|
||||||
|
|
||||||
|
public var groupName: String?
|
||||||
|
public var value: String?
|
||||||
|
public var fieldKey: String?
|
||||||
|
public var required: Bool = false
|
||||||
|
public var borderColor: Color = Color(uiColor: .black)
|
||||||
|
public var borderWidth: CGFloat = 1
|
||||||
|
public var isChecked: Bool = false
|
||||||
|
public var checkColor: Color = Color(uiColor: .black)
|
||||||
|
public var unCheckedBackgroundColor: Color = Color(uiColor: .clear)
|
||||||
|
public var checkedBackgroundColor: Color = Color(uiColor: .clear)
|
||||||
|
public var isAnimated: Bool = true
|
||||||
|
public var isRound: Bool = false
|
||||||
|
public var isEnabled: Bool = true
|
||||||
|
public var action: ActionModelProtocol?
|
||||||
|
public var disabledBackgroundColor: Color = Color(uiColor: .clear)
|
||||||
|
public var disabledBorderColor: Color = Color(uiColor: .mvmCoolGray3)
|
||||||
|
public var disabledCheckColor: Color = Color(uiColor: .mvmCoolGray3)
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Keys
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case groupName
|
||||||
|
case value
|
||||||
|
case fieldKey
|
||||||
|
case required
|
||||||
|
case borderColor
|
||||||
|
case borderWidth
|
||||||
|
case isChecked
|
||||||
|
case checkColor
|
||||||
|
case unCheckedBackgroundColor
|
||||||
|
case checkedBackgroundColor
|
||||||
|
case disabledBackgroundColor
|
||||||
|
case disabledCheckColor
|
||||||
|
case disabledBorderColor
|
||||||
|
case isAnimated
|
||||||
|
case isRound
|
||||||
|
case isEnabled
|
||||||
|
case action
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codec
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName)
|
||||||
|
value = try typeContainer.decodeIfPresent(String.self, forKey: .value)
|
||||||
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
|
required = try typeContainer.decodeIfPresent(Bool.self, forKey: .required) ?? false
|
||||||
|
borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) ?? 1
|
||||||
|
borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) ?? Color(uiColor: .black)
|
||||||
|
checkColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkColor) ?? Color(uiColor: .black)
|
||||||
|
unCheckedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .unCheckedBackgroundColor) ?? Color(uiColor: .clear)
|
||||||
|
checkedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkedBackgroundColor) ?? Color(uiColor: .clear)
|
||||||
|
disabledBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBackgroundColor) ?? Color(uiColor: .clear)
|
||||||
|
disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor) ?? Color(uiColor: .mvmCoolGray3)
|
||||||
|
disabledCheckColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledCheckColor) ?? Color(uiColor: .mvmCoolGray3)
|
||||||
|
isChecked = try typeContainer.decodeIfPresent(Bool.self, forKey: .isChecked) ?? false
|
||||||
|
isAnimated = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAnimated) ?? true
|
||||||
|
isRound = try typeContainer.decodeIfPresent(Bool.self, forKey: .isRound) ?? false
|
||||||
|
isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEnabled) ?? true
|
||||||
|
action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
|
try container.encodeIfPresent(value, forKey: .value)
|
||||||
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
|
try container.encodeIfPresent(required, forKey: .required)
|
||||||
|
try container.encodeIfPresent(borderColor, forKey: .borderColor)
|
||||||
|
try container.encode(borderWidth, forKey: .borderWidth)
|
||||||
|
try container.encode(isChecked, forKey: .isChecked)
|
||||||
|
try container.encodeIfPresent(checkColor, forKey: .checkColor)
|
||||||
|
try container.encodeIfPresent(unCheckedBackgroundColor, forKey: .unCheckedBackgroundColor)
|
||||||
|
try container.encodeIfPresent(checkedBackgroundColor, forKey: .checkedBackgroundColor)
|
||||||
|
try container.encodeIfPresent(disabledBorderColor, forKey: .disabledBorderColor)
|
||||||
|
try container.encodeIfPresent(disabledBackgroundColor, forKey: .disabledBackgroundColor)
|
||||||
|
try container.encodeIfPresent(disabledCheckColor, forKey: .disabledCheckColor)
|
||||||
|
try container.encodeIfPresent(isAnimated, forKey: .isAnimated)
|
||||||
|
try container.encodeIfPresent(isRound, forKey: .isRound)
|
||||||
|
try container.encodeIfPresent(isEnabled, forKey: .isEnabled)
|
||||||
|
try container.encodeModelIfPresent(action, forKey: .action)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,12 +21,6 @@
|
|||||||
|
|
||||||
public var checkboxPosition: CheckboxPosition = .center
|
public var checkboxPosition: CheckboxPosition = .center
|
||||||
|
|
||||||
public enum CheckboxPosition: String {
|
|
||||||
case center
|
|
||||||
case top
|
|
||||||
case bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Constraints
|
// MARK: - Constraints
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -120,6 +114,17 @@
|
|||||||
checkboxCenterYConstraint?.isActive = false
|
checkboxCenterYConstraint?.isActive = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
guard let checkBoxWithLabelModel = model as? CheckboxLabelModel else { return }
|
||||||
|
|
||||||
|
if let checkboxAlignment = checkBoxWithLabelModel.checkboxAlignment {
|
||||||
|
alignCheckbox(checkboxAlignment)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkbox.setWithModel(checkBoxWithLabelModel.checkbox, delegateObject, additionalData)
|
||||||
|
label.setWithModel(checkBoxWithLabelModel.label, delegateObject, additionalData)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Molecular
|
// MARK: - Molecular
|
||||||
|
|||||||
@ -19,8 +19,6 @@ open class DashLine: View {
|
|||||||
get { return model as? DashLineModel }
|
get { return model as? DashLineModel }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Legacy
|
|
||||||
@objc public var dashColor: UIColor?
|
|
||||||
@objc private var dashLayer: CAShapeLayer?
|
@objc private var dashLayer: CAShapeLayer?
|
||||||
|
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
@ -70,7 +68,7 @@ open class DashLine: View {
|
|||||||
dashLayer.lineCap = .round
|
dashLayer.lineCap = .round
|
||||||
dashLayer.lineDashPattern = [NSNumber(value: 2), NSNumber(value: 2)]
|
dashLayer.lineDashPattern = [NSNumber(value: 2), NSNumber(value: 2)]
|
||||||
dashLayer.path = path.cgPath
|
dashLayer.path = path.cgPath
|
||||||
dashLayer.strokeColor = dashModel?.dashColor.uiColor.cgColor ?? dashColor?.cgColor ?? UIColor.mfLighterGray().cgColor
|
dashLayer.strokeColor = dashModel?.dashColor.cgColor
|
||||||
dashLayer.fillColor = UIColor.clear.cgColor
|
dashLayer.fillColor = UIColor.clear.cgColor
|
||||||
dashLayer.backgroundColor = backgroundColor?.cgColor ?? UIColor.white.cgColor
|
dashLayer.backgroundColor = backgroundColor?.cgColor ?? UIColor.white.cgColor
|
||||||
self.dashLayer = dashLayer
|
self.dashLayer = dashLayer
|
||||||
@ -81,7 +79,7 @@ open class DashLine: View {
|
|||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
|
|
||||||
// Default values for view.
|
// Default values for view.
|
||||||
@objc open override func setAsMolecule() {
|
@objc open override func reset() {
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
isHidden = false
|
isHidden = false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -315,7 +315,7 @@ public typealias ActionBlock = () -> ()
|
|||||||
}
|
}
|
||||||
case let actionAtt as LabelAttributeActionModel:
|
case let actionAtt as LabelAttributeActionModel:
|
||||||
addTappableLinkAttribute(range: NSRange(location: range.location, length: range.length)) {
|
addTappableLinkAttribute(range: NSRange(location: range.location, length: range.length)) {
|
||||||
if let data = try? actionAtt.encode(using: JSONEncoder()), let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any] {
|
if let data = try? actionAtt.action.encode(using: JSONEncoder()), let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any] {
|
||||||
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,8 +12,8 @@ public typealias ButtonAction = (Button) -> ()
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
public var model: MoleculeModelProtocol?
|
open var model: MoleculeModelProtocol?
|
||||||
public var actionModel: ActionModelProtocol?
|
open var actionModel: ActionModelProtocol?
|
||||||
|
|
||||||
private var initialSetupPerformed = false
|
private var initialSetupPerformed = false
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ public typealias ButtonAction = (Button) -> ()
|
|||||||
// MARK: - Delegate
|
// MARK: - Delegate
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public weak var buttonDelegate: ButtonDelegateProtocol?
|
open weak var buttonDelegate: ButtonDelegateProtocol?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
@ -48,6 +48,7 @@ public typealias ButtonAction = (Button) -> ()
|
|||||||
// MARK: - Setup
|
// MARK: - Setup
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
/// Required to be called any init. Ensures setupView() only gets called once
|
||||||
public func initialSetup() {
|
public func initialSetup() {
|
||||||
|
|
||||||
if !initialSetupPerformed {
|
if !initialSetupPerformed {
|
||||||
@ -60,16 +61,17 @@ public typealias ButtonAction = (Button) -> ()
|
|||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public func addActionBlock( event: Event, _ buttonBlock: @escaping ButtonAction) {
|
/// Adds a block to be performed for the given event.
|
||||||
|
open func addActionBlock(event: Event, _ buttonBlock: @escaping ButtonAction) {
|
||||||
self.buttonAction = buttonBlock
|
self.buttonAction = buttonBlock
|
||||||
addTarget(self, action: #selector(callActionBlock(_:)), for: event)
|
addTarget(self, action: #selector(callActionBlock(_:)), for: event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func callActionBlock(_ sender: Button) {
|
@objc private func callActionBlock(_ sender: Button) {
|
||||||
buttonAction?(self)
|
buttonAction?(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func set(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
open func set(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||||
self.actionModel = actionModel
|
self.actionModel = actionModel
|
||||||
buttonDelegate = delegateObject?.buttonDelegate
|
buttonDelegate = delegateObject?.buttonDelegate
|
||||||
|
|
||||||
@ -104,14 +106,13 @@ public typealias ButtonAction = (Button) -> ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: - MVMCoreViewProtocol
|
// MARK: - MVMCoreViewProtocol
|
||||||
extension Button: MVMCoreViewProtocol {
|
extension Button: MVMCoreViewProtocol {
|
||||||
|
|
||||||
public func updateView(_ size: CGFloat) {}
|
open func updateView(_ size: CGFloat) {}
|
||||||
|
|
||||||
/// Will be called only once.
|
/// Will be called only once.
|
||||||
public func setupView() {
|
open func setupView() {
|
||||||
translatesAutoresizingMaskIntoConstraints = false
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
insetsLayoutMarginsFromSafeArea = false
|
insetsLayoutMarginsFromSafeArea = false
|
||||||
titleLabel?.numberOfLines = 0
|
titleLabel?.numberOfLines = 0
|
||||||
@ -121,7 +122,7 @@ extension Button: MVMCoreViewProtocol {
|
|||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||||
extension Button: MVMCoreUIMoleculeViewProtocol {
|
extension Button: MVMCoreUIMoleculeViewProtocol {
|
||||||
public func reset() {
|
open func reset() {
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import UIKit
|
|||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
open var json: [AnyHashable: Any]?
|
open var json: [AnyHashable: Any]?
|
||||||
public var model: MoleculeModelProtocol?
|
open var model: MoleculeModelProtocol?
|
||||||
|
|
||||||
private var initialSetupPerformed = false
|
private var initialSetupPerformed = false
|
||||||
|
|
||||||
@ -78,10 +78,10 @@ extension Control: AppleGuidelinesProtocol {
|
|||||||
// MARK: - MVMCoreViewProtocol
|
// MARK: - MVMCoreViewProtocol
|
||||||
extension Control: MVMCoreViewProtocol {
|
extension Control: MVMCoreViewProtocol {
|
||||||
|
|
||||||
public func updateView(_ size: CGFloat) {}
|
open func updateView(_ size: CGFloat) {}
|
||||||
|
|
||||||
/// Will be called only once.
|
/// Will be called only once.
|
||||||
public func setupView() {
|
open func setupView() {
|
||||||
translatesAutoresizingMaskIntoConstraints = false
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
insetsLayoutMarginsFromSafeArea = false
|
insetsLayoutMarginsFromSafeArea = false
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ extension Control: MVMCoreUIMoleculeViewProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func reset() {
|
open func reset() {
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,265 +0,0 @@
|
|||||||
//
|
|
||||||
// Container.swift
|
|
||||||
// MVMCoreUI
|
|
||||||
//
|
|
||||||
// Created by Scott Pfeil on 12/11/19.
|
|
||||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
public protocol ContainerModelProtocol: Model {
|
|
||||||
var horizontalAlignment: UIStackView.Alignment? { get set }
|
|
||||||
var verticalAlignment: UIStackView.Alignment? { get set }
|
|
||||||
var useHorizontalMargins: Bool? { get set }
|
|
||||||
var useVerticalMargins: Bool? { get set }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ContainerHelper: NSObject {
|
|
||||||
var leftConstraint: NSLayoutConstraint?
|
|
||||||
var topConstraint: NSLayoutConstraint?
|
|
||||||
var bottomConstraint: NSLayoutConstraint?
|
|
||||||
var rightConstraint: NSLayoutConstraint?
|
|
||||||
|
|
||||||
var alignCenterHorizontalConstraint: NSLayoutConstraint?
|
|
||||||
var alignCenterLeftConstraint: NSLayoutConstraint?
|
|
||||||
var alignCenterRightConstraint: NSLayoutConstraint?
|
|
||||||
|
|
||||||
var alignCenterVerticalConstraint: NSLayoutConstraint?
|
|
||||||
var alignCenterTopConstraint: NSLayoutConstraint?
|
|
||||||
var alignCenterBottomConstraint: NSLayoutConstraint?
|
|
||||||
|
|
||||||
var leftLowConstraint: NSLayoutConstraint?
|
|
||||||
var topLowConstraint: NSLayoutConstraint?
|
|
||||||
var bottomLowConstraint: NSLayoutConstraint?
|
|
||||||
var rightLowConstraint: NSLayoutConstraint?
|
|
||||||
|
|
||||||
func constrainView(_ view: UIView) {
|
|
||||||
guard let margins = view.superview?.layoutMarginsGuide else { return }
|
|
||||||
leftConstraint = view.leftAnchor.constraint(equalTo: margins.leftAnchor)
|
|
||||||
leftConstraint?.isActive = true
|
|
||||||
|
|
||||||
topConstraint = view.topAnchor.constraint(equalTo: margins.topAnchor)
|
|
||||||
topConstraint?.isActive = true
|
|
||||||
|
|
||||||
rightConstraint = margins.rightAnchor.constraint(equalTo: view.rightAnchor)
|
|
||||||
rightConstraint?.isActive = true
|
|
||||||
|
|
||||||
bottomConstraint = margins.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
|
||||||
bottomConstraint?.isActive = true
|
|
||||||
|
|
||||||
alignCenterHorizontalConstraint = view.centerXAnchor.constraint(equalTo: margins.centerXAnchor)
|
|
||||||
alignCenterLeftConstraint = view.leftAnchor.constraint(greaterThanOrEqualTo: margins.leftAnchor)
|
|
||||||
alignCenterRightConstraint = margins.rightAnchor.constraint(greaterThanOrEqualTo: view.rightAnchor)
|
|
||||||
|
|
||||||
alignCenterVerticalConstraint = view.centerYAnchor.constraint(equalTo: margins.centerYAnchor)
|
|
||||||
alignCenterTopConstraint = view.topAnchor.constraint(greaterThanOrEqualTo: margins.topAnchor)
|
|
||||||
alignCenterBottomConstraint = margins.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor)
|
|
||||||
|
|
||||||
leftLowConstraint = view.leftAnchor.constraint(equalTo: margins.leftAnchor)
|
|
||||||
leftLowConstraint?.priority = UILayoutPriority(rawValue: 200)
|
|
||||||
leftLowConstraint?.isActive = true
|
|
||||||
|
|
||||||
topLowConstraint = view.topAnchor.constraint(equalTo: margins.topAnchor)
|
|
||||||
topLowConstraint?.priority = UILayoutPriority(rawValue: 200)
|
|
||||||
topLowConstraint?.isActive = true
|
|
||||||
|
|
||||||
rightLowConstraint = margins.rightAnchor.constraint(equalTo: view.rightAnchor)
|
|
||||||
rightLowConstraint?.priority = UILayoutPriority(rawValue: 200)
|
|
||||||
rightLowConstraint?.isActive = true
|
|
||||||
|
|
||||||
bottomLowConstraint = margins.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
|
||||||
bottomLowConstraint?.priority = UILayoutPriority(rawValue: 200)
|
|
||||||
bottomLowConstraint?.isActive = true
|
|
||||||
|
|
||||||
setAccessibility(view)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setAccessibility(_ view: UIView) {
|
|
||||||
guard let superView = view.superview else { return }
|
|
||||||
superView.isAccessibilityElement = false
|
|
||||||
if let elements = view.accessibilityElements {
|
|
||||||
superView.accessibilityElements = elements
|
|
||||||
} else {
|
|
||||||
superView.accessibilityElements = [view]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func alignHorizontal(_ alignment: UIStackView.Alignment) {
|
|
||||||
switch alignment {
|
|
||||||
case .center:
|
|
||||||
alignCenterHorizontalConstraint?.isActive = true
|
|
||||||
alignCenterLeftConstraint?.isActive = true
|
|
||||||
alignCenterRightConstraint?.isActive = true
|
|
||||||
leftConstraint?.isActive = false
|
|
||||||
rightConstraint?.isActive = false
|
|
||||||
case .leading:
|
|
||||||
alignCenterHorizontalConstraint?.isActive = false
|
|
||||||
alignCenterLeftConstraint?.isActive = false
|
|
||||||
alignCenterRightConstraint?.isActive = true
|
|
||||||
leftConstraint?.isActive = true
|
|
||||||
rightConstraint?.isActive = false
|
|
||||||
case .trailing:
|
|
||||||
alignCenterHorizontalConstraint?.isActive = false
|
|
||||||
alignCenterLeftConstraint?.isActive = true
|
|
||||||
alignCenterRightConstraint?.isActive = false
|
|
||||||
leftConstraint?.isActive = false
|
|
||||||
rightConstraint?.isActive = true
|
|
||||||
case .fill:
|
|
||||||
alignCenterHorizontalConstraint?.isActive = false
|
|
||||||
alignCenterLeftConstraint?.isActive = false
|
|
||||||
alignCenterRightConstraint?.isActive = false
|
|
||||||
leftConstraint?.isActive = true
|
|
||||||
rightConstraint?.isActive = true
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func alignVertical(_ alignment: UIStackView.Alignment) {
|
|
||||||
switch alignment {
|
|
||||||
case .center:
|
|
||||||
alignCenterVerticalConstraint?.isActive = true
|
|
||||||
alignCenterTopConstraint?.isActive = true
|
|
||||||
alignCenterBottomConstraint?.isActive = true
|
|
||||||
topConstraint?.isActive = false
|
|
||||||
bottomConstraint?.isActive = false
|
|
||||||
case .leading:
|
|
||||||
alignCenterVerticalConstraint?.isActive = false
|
|
||||||
alignCenterTopConstraint?.isActive = false
|
|
||||||
alignCenterBottomConstraint?.isActive = true
|
|
||||||
topConstraint?.isActive = true
|
|
||||||
bottomConstraint?.isActive = false
|
|
||||||
case .trailing:
|
|
||||||
alignCenterVerticalConstraint?.isActive = false
|
|
||||||
alignCenterTopConstraint?.isActive = true
|
|
||||||
alignCenterBottomConstraint?.isActive = false
|
|
||||||
topConstraint?.isActive = false
|
|
||||||
bottomConstraint?.isActive = true
|
|
||||||
case .fill:
|
|
||||||
alignCenterVerticalConstraint?.isActive = false
|
|
||||||
alignCenterTopConstraint?.isActive = false
|
|
||||||
alignCenterBottomConstraint?.isActive = false
|
|
||||||
topConstraint?.isActive = true
|
|
||||||
bottomConstraint?.isActive = true
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func set(with model: ContainerModelProtocol) {
|
|
||||||
if let horizontalAlignment = model.horizontalAlignment {
|
|
||||||
alignHorizontal(horizontalAlignment)
|
|
||||||
}
|
|
||||||
if let verticalAlignment = model.verticalAlignment {
|
|
||||||
alignVertical(verticalAlignment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static func getAlignment(for string: String) -> UIStackView.Alignment? {
|
|
||||||
switch string {
|
|
||||||
case "leading":
|
|
||||||
return .leading
|
|
||||||
case "trailing":
|
|
||||||
return .trailing
|
|
||||||
case "center":
|
|
||||||
return .center
|
|
||||||
case "fill":
|
|
||||||
return .fill
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static func getAlignmentString(for alignment: UIStackView.Alignment?) -> String? {
|
|
||||||
switch alignment {
|
|
||||||
case .leading:
|
|
||||||
return "leading"
|
|
||||||
case .trailing:
|
|
||||||
return "trailing"
|
|
||||||
case .center:
|
|
||||||
return "center"
|
|
||||||
case .fill:
|
|
||||||
return "fill"
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func set(with JSON: [AnyHashable: Any]?, for contained: UIView) {
|
|
||||||
if let horizontalAlignmentString = JSON?.optionalStringForKey("horizontalAlignment"), let alignment = ContainerHelper.getAlignment(for: horizontalAlignmentString) ?? (contained as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() {
|
|
||||||
alignHorizontal(alignment)
|
|
||||||
} else if let alignment = (contained as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() {
|
|
||||||
alignHorizontal(alignment)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let verticalAlignmentString = JSON?.optionalStringForKey("verticalAlignment"), let alignment = ContainerHelper.getAlignment(for: verticalAlignmentString) ?? (contained as? MVMCoreUIViewConstrainingProtocol)?.verticalAlignment?() {
|
|
||||||
alignVertical(alignment)
|
|
||||||
} else if let alignment = (contained as? MVMCoreUIViewConstrainingProtocol)?.verticalAlignment?() {
|
|
||||||
alignVertical(alignment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open class Container: View {
|
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
var containerModel: ContainerModelProtocol?
|
|
||||||
>>>>>>> e36d487d326f710d7302c6d9bcb758d209ad329c
|
|
||||||
var view: UIView?
|
|
||||||
let containerHelper = ContainerHelper()
|
|
||||||
var containerModel: ContainerModelProtocol? {
|
|
||||||
get { return model as? ContainerModelProtocol }
|
|
||||||
}
|
|
||||||
var topMarginPadding: CGFloat = 0
|
|
||||||
var bottomMarginPadding: CGFloat = 0
|
|
||||||
|
|
||||||
override open func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
|
||||||
super.setWithModel(model, delegateObject, additionalData)
|
|
||||||
guard let containerModel = model as? ContainerModelProtocol else { return }
|
|
||||||
containerHelper.set(with: containerModel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - MVMCoreViewProtocol
|
|
||||||
public extension Container {
|
|
||||||
override func updateView(_ size: CGFloat) {
|
|
||||||
super.updateView(size)
|
|
||||||
(view as? MVMCoreViewProtocol)?.updateView(size)
|
|
||||||
MFStyler.setMarginsFor(self, size: size, defaultHorizontal: containerModel?.useHorizontalMargins ?? true, top: containerModel?.useHorizontalMargins ?? true ? topMarginPadding : 0, bottom: containerModel?.useHorizontalMargins ?? true ? bottomMarginPadding : 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Will be called only once.
|
|
||||||
override func setupView() {
|
|
||||||
super.setupView()
|
|
||||||
backgroundColor = .clear
|
|
||||||
}
|
|
||||||
|
|
||||||
func addAndContain(_ view: UIView) {
|
|
||||||
view.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
addSubview(view)
|
|
||||||
containerHelper.constrainView(view)
|
|
||||||
self.view = view
|
|
||||||
}
|
|
||||||
|
|
||||||
convenience init(andContain view: UIView) {
|
|
||||||
self.init()
|
|
||||||
addAndContain(view)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
|
||||||
public extension Container {
|
|
||||||
override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
guard let view = view else { return }
|
|
||||||
containerHelper.set(with: json, for: view)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func reset() {
|
|
||||||
super.reset()
|
|
||||||
(view as? MVMCoreUIMoleculeViewProtocol)?.reset?()
|
|
||||||
}
|
|
||||||
|
|
||||||
func setAsMolecule() {
|
|
||||||
(view as? MVMCoreUIMoleculeViewProtocol)?.setAsMolecule?()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,285 +0,0 @@
|
|||||||
//
|
|
||||||
// EntryFieldContainer.swift
|
|
||||||
// MVMCoreUI
|
|
||||||
//
|
|
||||||
// Created by Kevin Christiano on 11/12/19.
|
|
||||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
|
|
||||||
@objcMembers open class EntryFieldContainer: View {
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Drawing Properties
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
/// The bottom border line. Height is dynamic based on scenario.
|
|
||||||
public var bottomBar: CAShapeLayer? = {
|
|
||||||
let layer = CAShapeLayer()
|
|
||||||
layer.backgroundColor = UIColor.black.cgColor
|
|
||||||
layer.drawsAsynchronously = true
|
|
||||||
layer.anchorPoint = CGPoint(x: 0.5, y: 1.0);
|
|
||||||
return layer
|
|
||||||
}()
|
|
||||||
|
|
||||||
/// Total control over the drawn top, bottom, left and right borders.
|
|
||||||
public var disableAllBorders = false {
|
|
||||||
didSet {
|
|
||||||
bottomBar?.isHidden = disableAllBorders
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private(set) var fieldState: FieldState = .original {
|
|
||||||
didSet (oldState) {
|
|
||||||
// Will not update if new state is the same as old.
|
|
||||||
if fieldState != oldState {
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
|
||||||
guard let self = self else { return }
|
|
||||||
|
|
||||||
self.fieldState.setStateUI(for: self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determines if the top, left, and right borders should be drawn.
|
|
||||||
private var hideBorders = false
|
|
||||||
|
|
||||||
public var borderStrokeColor: UIColor = .mfSilver()
|
|
||||||
private var borderPath: UIBezierPath = UIBezierPath()
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Property Observers
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
private var _isEnabled: Bool = true
|
|
||||||
private var _showError: Bool = false
|
|
||||||
private var _isLocked: Bool = false
|
|
||||||
private var _isSelected: Bool = false
|
|
||||||
|
|
||||||
public var isEnabled: Bool {
|
|
||||||
get { return _isEnabled }
|
|
||||||
set (enabled) {
|
|
||||||
|
|
||||||
_isEnabled = enabled
|
|
||||||
_isLocked = false
|
|
||||||
_isSelected = false
|
|
||||||
_showError = false
|
|
||||||
|
|
||||||
fieldState = enabled ? .original : .disabled
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public var showError: Bool {
|
|
||||||
get { return _showError }
|
|
||||||
set (error) {
|
|
||||||
|
|
||||||
_showError = error
|
|
||||||
_isEnabled = true
|
|
||||||
_isLocked = false
|
|
||||||
_isSelected = false
|
|
||||||
|
|
||||||
fieldState = error ? .error : .original
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public var isLocked: Bool {
|
|
||||||
get { return _isLocked }
|
|
||||||
set (locked) {
|
|
||||||
|
|
||||||
_isLocked = locked
|
|
||||||
_isEnabled = true
|
|
||||||
_isSelected = false
|
|
||||||
_showError = false
|
|
||||||
|
|
||||||
fieldState = locked ? .locked : .original
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public var isSelected: Bool {
|
|
||||||
get { return _isSelected }
|
|
||||||
set (selected) {
|
|
||||||
|
|
||||||
_isSelected = selected
|
|
||||||
_isLocked = false
|
|
||||||
_isEnabled = true
|
|
||||||
|
|
||||||
if _showError {
|
|
||||||
fieldState = selected ? .selectedError : .error
|
|
||||||
} else {
|
|
||||||
fieldState = selected ? .selected : .original
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Delegate
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
/// Holds reference to delegateObject to inform molecular tableView of an update.
|
|
||||||
weak var delegateObject: MVMCoreUIDelegateObject?
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Lifecycle
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
open override func layoutSubviews() {
|
|
||||||
super.layoutSubviews()
|
|
||||||
|
|
||||||
refreshUI(bottomBarSize: showError ? 4 : 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
open override func updateView(_ size: CGFloat) {
|
|
||||||
super.updateView(size)
|
|
||||||
|
|
||||||
refreshUI()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This handles the top, left, and right border lines.
|
|
||||||
open override func draw(_ rect: CGRect) {
|
|
||||||
super.draw(rect)
|
|
||||||
|
|
||||||
borderPath.removeAllPoints()
|
|
||||||
|
|
||||||
if !disableAllBorders && !hideBorders {
|
|
||||||
// Brings the other half of the line inside the view to prevent cropping.
|
|
||||||
let origin = bounds.origin
|
|
||||||
let size = frame.size
|
|
||||||
let insetLean: CGFloat = 0.5
|
|
||||||
borderPath.lineWidth = 1
|
|
||||||
|
|
||||||
borderPath.move(to: CGPoint(x: origin.x + insetLean, y: origin.y + size.height))
|
|
||||||
borderPath.addLine(to: CGPoint(x: origin.x + insetLean, y: origin.y + insetLean))
|
|
||||||
borderPath.addLine(to: CGPoint(x: origin.x + size.width - insetLean, y: origin.y + insetLean))
|
|
||||||
borderPath.addLine(to: CGPoint(x: origin.x + size.width - insetLean, y: origin.y + size.height))
|
|
||||||
|
|
||||||
borderStrokeColor.setStroke()
|
|
||||||
borderPath.stroke()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override open func setupView() {
|
|
||||||
super.setupView()
|
|
||||||
|
|
||||||
isAccessibilityElement = false
|
|
||||||
isOpaque = false
|
|
||||||
|
|
||||||
if let bottomBar = bottomBar {
|
|
||||||
layer.addSublayer(bottomBar)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Draw States
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
public enum FieldState {
|
|
||||||
case original
|
|
||||||
case error
|
|
||||||
case selectedError
|
|
||||||
case selected
|
|
||||||
case locked
|
|
||||||
case disabled
|
|
||||||
|
|
||||||
public func setStateUI(for formField: EntryFieldContainer) {
|
|
||||||
|
|
||||||
switch self {
|
|
||||||
case .original:
|
|
||||||
formField.originalUI()
|
|
||||||
|
|
||||||
case .error:
|
|
||||||
formField.errorUI()
|
|
||||||
|
|
||||||
case .selectedError:
|
|
||||||
formField.selectedErrorUI()
|
|
||||||
|
|
||||||
case .selected:
|
|
||||||
formField.selectedUI()
|
|
||||||
|
|
||||||
case .locked:
|
|
||||||
formField.lockedUI()
|
|
||||||
|
|
||||||
case .disabled:
|
|
||||||
formField.disabledUI()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open func originalUI() {
|
|
||||||
|
|
||||||
isUserInteractionEnabled = true
|
|
||||||
hideBorders = false
|
|
||||||
borderStrokeColor = .mfSilver()
|
|
||||||
bottomBar?.backgroundColor = UIColor.black.cgColor
|
|
||||||
refreshUI(bottomBarSize: 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
open func errorUI() {
|
|
||||||
|
|
||||||
isUserInteractionEnabled = true
|
|
||||||
hideBorders = false
|
|
||||||
borderStrokeColor = .mfPumpkin()
|
|
||||||
bottomBar?.backgroundColor = UIColor.mfPumpkin().cgColor
|
|
||||||
refreshUI(bottomBarSize: 4)
|
|
||||||
}
|
|
||||||
|
|
||||||
open func selectedErrorUI() {
|
|
||||||
|
|
||||||
isUserInteractionEnabled = true
|
|
||||||
hideBorders = false
|
|
||||||
borderStrokeColor = .black
|
|
||||||
bottomBar?.backgroundColor = UIColor.mfPumpkin().cgColor
|
|
||||||
refreshUI(bottomBarSize: 4)
|
|
||||||
}
|
|
||||||
|
|
||||||
open func selectedUI() {
|
|
||||||
|
|
||||||
isUserInteractionEnabled = true
|
|
||||||
hideBorders = false
|
|
||||||
borderStrokeColor = .black
|
|
||||||
bottomBar?.backgroundColor = UIColor.black.cgColor
|
|
||||||
refreshUI(bottomBarSize: 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
open func lockedUI() {
|
|
||||||
|
|
||||||
isUserInteractionEnabled = false
|
|
||||||
hideBorders = true
|
|
||||||
borderStrokeColor = .clear
|
|
||||||
bottomBar?.backgroundColor = UIColor.clear.cgColor
|
|
||||||
refreshUI(bottomBarSize: 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
open func disabledUI() {
|
|
||||||
|
|
||||||
isUserInteractionEnabled = false
|
|
||||||
hideBorders = false
|
|
||||||
borderStrokeColor = .mfSilver()
|
|
||||||
bottomBar?.backgroundColor = UIColor.mfSilver().cgColor
|
|
||||||
refreshUI(bottomBarSize: 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
open func refreshUI(bottomBarSize: CGFloat? = nil) {
|
|
||||||
|
|
||||||
if !disableAllBorders {
|
|
||||||
let size: CGFloat = bottomBarSize ?? (showError ? 4 : 1)
|
|
||||||
bottomBar?.frame = CGRect(x: 0, y: bounds.height - size, width: bounds.width, height: size)
|
|
||||||
|
|
||||||
delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self)
|
|
||||||
setNeedsDisplay()
|
|
||||||
layoutIfNeeded()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK:- MVMCoreUIMoleculeViewProtocol
|
|
||||||
extension EntryFieldContainer {
|
|
||||||
|
|
||||||
override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
self.delegateObject = delegateObject
|
|
||||||
|
|
||||||
guard let dictionary = json, !dictionary.isEmpty else { return }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
//
|
|
||||||
// FooterModel.swift
|
|
||||||
// MVMCoreUI
|
|
||||||
//
|
|
||||||
// Created by Suresh, Kamlesh on 11/27/19.
|
|
||||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class FooterModel: MoleculeContainerModel, MoleculeProtocol {
|
|
||||||
public static var identifier: String = "footer"
|
|
||||||
public var backgroundColor: Color?
|
|
||||||
|
|
||||||
enum FooterCodingKeys: String, CodingKey {
|
|
||||||
case backgroundColor
|
|
||||||
}
|
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
|
||||||
<<<<<<< HEAD
|
|
||||||
let typeContainer = try decoder.container(keyedBy: FooterCodingKeys.self)
|
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
|
||||||
try super.init(from: decoder)
|
|
||||||
=======
|
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
self.backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
|
||||||
self.molecule = try typeContainer.decodeMolecule(codingKey: .molecule)
|
|
||||||
>>>>>>> 83b0a554049f764888ce9db27dbd7fa503fddf01
|
|
||||||
}
|
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
|
||||||
try super.encode(to: encoder)
|
|
||||||
var container = encoder.container(keyedBy: FooterCodingKeys.self)
|
|
||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,100 +0,0 @@
|
|||||||
//
|
|
||||||
// StackItem.swift
|
|
||||||
// MVMCoreUI
|
|
||||||
//
|
|
||||||
// Created by Scott Pfeil on 12/13/19.
|
|
||||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
open class StackItemModel: ContainerModelProtocol, MoleculeProtocol {
|
|
||||||
public static var identifier: String = "stackItem"
|
|
||||||
public var backgroundColor: String?
|
|
||||||
public var view: StackItem?
|
|
||||||
|
|
||||||
public var molecule: MoleculeProtocol
|
|
||||||
public var spacing: CGFloat? = 16
|
|
||||||
public var percentage: Int? = 0
|
|
||||||
public var verticalAlignment: UIStackView.Alignment?
|
|
||||||
public var horizontalAlignment: UIStackView.Alignment?
|
|
||||||
public var useHorizontalMargins: Bool? = false
|
|
||||||
public var useVerticalMargins: Bool? = false
|
|
||||||
public var gone: Bool? = false
|
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case molecule
|
|
||||||
case spacing
|
|
||||||
case percentage
|
|
||||||
case verticalAlignment
|
|
||||||
case horizontalAlignment
|
|
||||||
case useHorizontalMargins
|
|
||||||
case useVerticalMargins
|
|
||||||
case gone
|
|
||||||
}
|
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
molecule = try typeContainer.decodeMolecule(codingKey: .molecule)
|
|
||||||
spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing)
|
|
||||||
percentage = try typeContainer.decodeIfPresent(Int.self, forKey: .percentage)
|
|
||||||
if let verticalAlignmentString = try typeContainer.decodeIfPresent(String.self, forKey: .verticalAlignment) {
|
|
||||||
verticalAlignment = ContainerHelper.getAlignment(for: verticalAlignmentString)
|
|
||||||
}
|
|
||||||
if let horizontalAlignmentString = try typeContainer.decodeIfPresent(String.self, forKey: .horizontalAlignment) {
|
|
||||||
horizontalAlignment = ContainerHelper.getAlignment(for: horizontalAlignmentString)
|
|
||||||
}
|
|
||||||
useVerticalMargins = try typeContainer.decodeIfPresent(Bool.self, forKey: .useVerticalMargins)
|
|
||||||
useHorizontalMargins = try typeContainer.decodeIfPresent(Bool.self, forKey: .useHorizontalMargins)
|
|
||||||
gone = try typeContainer.decodeIfPresent(Bool.self, forKey: .gone)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
||||||
try container.encodeModel(molecule, forKey: .molecule)
|
|
||||||
try container.encodeIfPresent(spacing, forKey: .spacing)
|
|
||||||
try container.encodeIfPresent(percentage, forKey: .percentage)
|
|
||||||
try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: verticalAlignment), forKey: .verticalAlignment)
|
|
||||||
try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: horizontalAlignment), forKey: .horizontalAlignment)
|
|
||||||
try container.encodeIfPresent(useVerticalMargins, forKey: .useVerticalMargins)
|
|
||||||
try container.encodeIfPresent(useHorizontalMargins, forKey: .useHorizontalMargins)
|
|
||||||
try container.encodeIfPresent(gone, forKey: .gone)
|
|
||||||
=======
|
|
||||||
init(with view: StackItem) {
|
|
||||||
self.view = view
|
|
||||||
view.containerModel = self
|
|
||||||
}
|
|
||||||
|
|
||||||
init(with view: StackItem, json: [AnyHashable: Any]?) {
|
|
||||||
self.view = view
|
|
||||||
view.containerModel = self
|
|
||||||
update(with: json)
|
|
||||||
>>>>>>> e36d487d326f710d7302c6d9bcb758d209ad329c
|
|
||||||
}
|
|
||||||
|
|
||||||
func update(with json: [AnyHashable: Any]?) {
|
|
||||||
gone = json?.boolForKey("gone") ?? (json == nil)
|
|
||||||
spacing = json?.optionalCGFloatForKey("spacing")
|
|
||||||
percentage = json?["percent"] as? Int
|
|
||||||
if let horizontalAlignmentString = json?.optionalStringForKey("horizontalAlignment") {
|
|
||||||
horizontalAlignment = ContainerHelper.getAlignment(for: horizontalAlignmentString)
|
|
||||||
} else {
|
|
||||||
horizontalAlignment = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if let verticalAlignmentString = json?.optionalStringForKey("verticalAlignment") {
|
|
||||||
verticalAlignment = ContainerHelper.getAlignment(for: verticalAlignmentString)
|
|
||||||
} else {
|
|
||||||
verticalAlignment = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
useHorizontalMargins = json?.optionalBoolForKey("useHorizontalMargins") ?? false
|
|
||||||
useVerticalMargins = json?.optionalBoolForKey("useVerticalMargins") ?? false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open class StackItem: MoleculeContainer {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -137,6 +137,7 @@ import UIKit
|
|||||||
open func setupView() {
|
open func setupView() {
|
||||||
selectionStyle = .none
|
selectionStyle = .none
|
||||||
insetsLayoutMarginsFromSafeArea = false
|
insetsLayoutMarginsFromSafeArea = false
|
||||||
|
preservesSuperviewLayoutMargins = false
|
||||||
contentView.insetsLayoutMarginsFromSafeArea = false
|
contentView.insetsLayoutMarginsFromSafeArea = false
|
||||||
contentView.preservesSuperviewLayoutMargins = false
|
contentView.preservesSuperviewLayoutMargins = false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,116 +0,0 @@
|
|||||||
//
|
|
||||||
// ModuleMolecule.swift
|
|
||||||
// MVMCoreUI
|
|
||||||
//
|
|
||||||
// Created by Scott Pfeil on 6/25/19.
|
|
||||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
open class ModuleMoleculeModel: ContainerModelProtocol {
|
|
||||||
public static var identifier: String = "moduleMolecule"
|
|
||||||
|
|
||||||
public var molecule: MoleculeProtocol?
|
|
||||||
public var moduleName: String
|
|
||||||
public var horizontalAlignment: UIStackView.Alignment? = .fill
|
|
||||||
public var verticalAlignment: UIStackView.Alignment? = .fill
|
|
||||||
public var useHorizontalMargins: Bool? = false
|
|
||||||
public var useVerticalMargins: Bool? = false
|
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case molecule
|
|
||||||
case moduleName
|
|
||||||
case horizontalAlignment
|
|
||||||
case verticalAlignment
|
|
||||||
case useHorizontalMargins
|
|
||||||
case useVerticalMargins
|
|
||||||
}
|
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
moduleName = try typeContainer.decode(String.self, forKey:.moduleName)
|
|
||||||
if let verticalAlignmentString = try typeContainer.decodeIfPresent(String.self, forKey: .verticalAlignment) {
|
|
||||||
verticalAlignment = ContainerHelper.getAlignment(for: verticalAlignmentString)
|
|
||||||
}
|
|
||||||
if let horizontalAlignmentString = try typeContainer.decodeIfPresent(String.self, forKey: .horizontalAlignment) {
|
|
||||||
horizontalAlignment = ContainerHelper.getAlignment(for: horizontalAlignmentString)
|
|
||||||
}
|
|
||||||
useVerticalMargins = try typeContainer.decodeIfPresent(Bool.self, forKey: .useVerticalMargins)
|
|
||||||
useHorizontalMargins = try typeContainer.decodeIfPresent(Bool.self, forKey: .useHorizontalMargins)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
||||||
try container.encode(moduleName, forKey: .moduleName)
|
|
||||||
try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: verticalAlignment), forKey: .verticalAlignment)
|
|
||||||
try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: horizontalAlignment), forKey: .horizontalAlignment)
|
|
||||||
try container.encodeIfPresent(useVerticalMargins, forKey: .useVerticalMargins)
|
|
||||||
try container.encodeIfPresent(useHorizontalMargins, forKey: .useHorizontalMargins)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open class ModuleMolecule: Container {
|
|
||||||
<<<<<<< HEAD
|
|
||||||
var moduleMoleculeModel: ModuleMoleculeModel? {
|
|
||||||
get { return model as? ModuleMoleculeModel }
|
|
||||||
=======
|
|
||||||
public override func setupView() {
|
|
||||||
super.setupView()
|
|
||||||
containerModel = ModuleMoleculeModel()
|
|
||||||
>>>>>>> e36d487d326f710d7302c6d9bcb758d209ad329c
|
|
||||||
}
|
|
||||||
|
|
||||||
open override func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
|
||||||
#warning("need to change getter to get moduleModel instead to use.")
|
|
||||||
super.setWithModel(model, delegateObject, additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
|
||||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
|
|
||||||
guard let moduleName = json?.optionalStringForKey("moduleName"), let module = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
|
|
||||||
// Critical error
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if view == nil {
|
|
||||||
if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: module, delegateObject: delegateObject, constrainIfNeeded: false) {
|
|
||||||
addAndContain(moleculeView)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
(view as? MVMCoreUIMoleculeViewProtocol)?.setWithJSON(module, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
|
||||||
guard let moduleName = json?.optionalStringForKey("moduleName"), let module = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
|
|
||||||
// Critical error
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: module)?.estimatedHeight?(forRow: module, delegateObject: delegateObject) ?? 0
|
|
||||||
}
|
|
||||||
|
|
||||||
public class func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
|
||||||
guard let moduleName = molecule?.optionalStringForKey("moduleName"), let module = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
|
|
||||||
// Critical error
|
|
||||||
return "moduleMolecule<>"
|
|
||||||
}
|
|
||||||
return "moduleMolecule<" + (MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: module)?.name?(forReuse: module, delegateObject: delegateObject) ?? module.stringForkey(KeyMoleculeName)) + ">"
|
|
||||||
}
|
|
||||||
|
|
||||||
public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
|
||||||
let moduleName = json?.optionalStringForKey("moduleName")
|
|
||||||
if moduleName == nil || delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) == nil {
|
|
||||||
if let errorObject = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess), code: CoreUIErrorCode.ErrorCodeModuleMolecule.rawValue, domain: ErrorDomainNative, location: String(describing: self)) {
|
|
||||||
error?.pointee = errorObject
|
|
||||||
MVMCoreUILoggingHandler.shared()?.addError(toLog: errorObject)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let moduleName = moduleName {
|
|
||||||
return [moduleName]
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
//
|
|
||||||
// StandardHeaderView.swift
|
|
||||||
// MVMCoreUI
|
|
||||||
//
|
|
||||||
// Created by Scott Pfeil on 2/12/19.
|
|
||||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
public class StandardHeaderView: MoleculeContainer {
|
|
||||||
var line: Line?
|
|
||||||
|
|
||||||
// MARK: - MVMCoreViewProtocol
|
|
||||||
open override func updateView(_ size: CGFloat) {
|
|
||||||
super.updateView(size)
|
|
||||||
line?.updateView(size)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override func setupView() {
|
|
||||||
super.setupView()
|
|
||||||
topMarginPadding = PaddingDefaultVerticalSpacing
|
|
||||||
bottomMarginPadding = PaddingDefaultVerticalSpacing
|
|
||||||
|
|
||||||
guard line == nil else { return }
|
|
||||||
let line = Line()
|
|
||||||
line.style = .heavy
|
|
||||||
addSubview(line)
|
|
||||||
NSLayoutConstraint.pinViewBottom(toSuperview: line, useMargins: false, constant: 0).isActive = true
|
|
||||||
NSLayoutConstraint.pinViewLeft(toSuperview: line, useMargins: true, constant: 0).isActive = true
|
|
||||||
NSLayoutConstraint.pinViewRight(toSuperview: line, useMargins: true, constant: 0).isActive = true
|
|
||||||
self.line = line
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
|
||||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
|
||||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
if let separatorJSON = json?.optionalDictionaryForKey("separator") {
|
|
||||||
line?.setWithJSON(separatorJSON, delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
open override func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
|
||||||
super.setWithModel(model, delegateObject, additionalData)
|
|
||||||
|
|
||||||
guard let headerModel = model as? HeaderModel else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if let seperatorModel = headerModel.seperator as? LineModel {
|
|
||||||
line?.setWithJSON(seperatorModel.toJSON(), delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
=======
|
|
||||||
// open func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
|
||||||
// //TODO: Need to create setWithModel in ViewConstraining View
|
|
||||||
//
|
|
||||||
// #warning("This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView.")
|
|
||||||
// //TODO: This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView.
|
|
||||||
// setUpWithModel(model, delegateObject, additionalData)
|
|
||||||
//
|
|
||||||
// // This molecule will by default handle margins.
|
|
||||||
// (molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(false)
|
|
||||||
// (molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(false)
|
|
||||||
//
|
|
||||||
// guard let headerModel = model as? HeaderModel else {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if let seperatorModel = headerModel.seperator as? LineModel {
|
|
||||||
// line?.setWithJSON(seperatorModel.toJSON(), delegateObject: delegateObject, additionalData: additionalData)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
>>>>>>> e36d487d326f710d7302c6d9bcb758d209ad329c
|
|
||||||
|
|
||||||
open override func reset() {
|
|
||||||
super.reset()
|
|
||||||
line?.style = .heavy
|
|
||||||
topMarginPadding = PaddingDefaultVerticalSpacing
|
|
||||||
bottomMarginPadding = PaddingDefaultVerticalSpacing
|
|
||||||
}
|
|
||||||
|
|
||||||
public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
|
||||||
if let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule), let height = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON)?.estimatedHeight?(forRow: moleculeJSON, delegateObject: delegateObject) {
|
|
||||||
return height + PaddingDefaultVerticalSpacing + PaddingDefaultVerticalSpacing
|
|
||||||
}
|
|
||||||
return 121
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -7,13 +7,15 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
@objcMembers public class HeadLineBodyCaretLinkImage: View {
|
@objcMembers public class HeadLineBodyCaretLinkImage: Container {
|
||||||
|
|
||||||
let headlineBody = HeadlineBody(frame: .zero)
|
let headlineBody = HeadlineBody(frame: .zero)
|
||||||
let caretButton = CaretButton(frame: .zero)
|
let caretButton = CaretButton(frame: .zero)
|
||||||
let backgroundImageView = MFLoadImageView()
|
let backgroundImageView = MFLoadImageView(pinnedEdges: .all)
|
||||||
var spaceBetweenConstant: CGFloat = 104.0
|
var spaceBetweenConstant: CGFloat = 104.0
|
||||||
let maxWidth : CGFloat = 350.0
|
let maxWidth: CGFloat = 350.0
|
||||||
|
static let heightConstant: CGFloat = 320.0
|
||||||
|
var heightConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
// MARK: - MVMCoreViewProtocol
|
// MARK: - MVMCoreViewProtocol
|
||||||
open override func updateView(_ size: CGFloat) {
|
open override func updateView(_ size: CGFloat) {
|
||||||
super.updateView(size)
|
super.updateView(size)
|
||||||
@ -29,25 +31,28 @@ import Foundation
|
|||||||
guard subviews.count == 0 else {
|
guard subviews.count == 0 else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let view = MVMCoreUICommonViewsUtility.commonView()
|
heightConstraint = heightAnchor.constraint(equalToConstant: Self.heightConstant)
|
||||||
addSubview(view)
|
heightConstraint?.isActive = true
|
||||||
NSLayoutConstraint.constraintPinSubview(toSuperview: view)
|
|
||||||
view.addSubview(headlineBody)
|
let container = MVMCoreUICommonViewsUtility.commonView()
|
||||||
view.addSubview(caretButton)
|
addAndContain(container)
|
||||||
|
|
||||||
|
container.addSubview(headlineBody)
|
||||||
|
container.addSubview(caretButton)
|
||||||
|
|
||||||
//Headline view
|
//Headline view
|
||||||
headlineBody.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
|
headlineBody.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true
|
||||||
headlineBody.topAnchor.constraint(equalTo: view.topAnchor, constant: PaddingDefault).isActive = true
|
headlineBody.topAnchor.constraint(equalTo: container.topAnchor, constant: 0).isActive = true
|
||||||
|
|
||||||
let headLineBodyWidth = headlineBody.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.85)
|
let headLineBodyWidth = headlineBody.widthAnchor.constraint(equalTo: container.widthAnchor, multiplier: 0.85)
|
||||||
headLineBodyWidth.priority = .defaultHigh
|
headLineBodyWidth.priority = .defaultHigh
|
||||||
headLineBodyWidth.isActive = true
|
headLineBodyWidth.isActive = true
|
||||||
headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: maxWidth).isActive = true
|
headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: maxWidth).isActive = true
|
||||||
|
|
||||||
//Caret view
|
//Caret view
|
||||||
caretButton.translatesAutoresizingMaskIntoConstraints = false
|
caretButton.translatesAutoresizingMaskIntoConstraints = false
|
||||||
caretButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
|
caretButton.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true
|
||||||
view.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor, constant: PaddingDefault).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: spaceBetweenConstant).isActive = true
|
||||||
|
|
||||||
@ -56,9 +61,9 @@ import Foundation
|
|||||||
backgroundImageView.imageView.contentMode = .scaleAspectFill
|
backgroundImageView.imageView.contentMode = .scaleAspectFill
|
||||||
backgroundImageView.alignFillHorizontal()
|
backgroundImageView.alignFillHorizontal()
|
||||||
backgroundImageView.alignFillVertical()
|
backgroundImageView.alignFillVertical()
|
||||||
view.addSubview(backgroundImageView)
|
addSubview(backgroundImageView)
|
||||||
NSLayoutConstraint.constraintPinSubview(toSuperview: backgroundImageView)
|
NSLayoutConstraint.constraintPinSubview(toSuperview: backgroundImageView)
|
||||||
view.sendSubviewToBack(backgroundImageView)
|
sendSubviewToBack(backgroundImageView)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||||
@ -85,6 +90,7 @@ import Foundation
|
|||||||
guard let model = model as? HeadlineBodyCaretLinkImageModel else { return }
|
guard let model = model as? HeadlineBodyCaretLinkImageModel else { return }
|
||||||
headlineBody.setWithModel(model.headlineBody, delegateObject, additionalData)
|
headlineBody.setWithModel(model.headlineBody, delegateObject, additionalData)
|
||||||
caretButton.setWithModel(model.caretLink, delegateObject, additionalData)
|
caretButton.setWithModel(model.caretLink, delegateObject, additionalData)
|
||||||
|
caretButton.isHidden = model.caretLink == nil
|
||||||
backgroundImageView.setWithModel(model.image, delegateObject, additionalData)
|
backgroundImageView.setWithModel(model.image, delegateObject, additionalData)
|
||||||
backgroundImageView.alignFillHorizontal()
|
backgroundImageView.alignFillHorizontal()
|
||||||
backgroundImageView.alignFillVertical()
|
backgroundImageView.alignFillVertical()
|
||||||
|
|||||||
@ -8,10 +8,64 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
public class HeadlineBodyCaretLinkImageModel: MoleculeModelProtocol {
|
public class HeadlineBodyCaretLinkImageModel: ContainerModel, MoleculeModelProtocol {
|
||||||
public static var identifier: String = "headlineBodyCaretLinkImage"
|
public static var identifier: String = "headlineBodyCaretLinkImage"
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var caretLink: CaretLinkModel?
|
public var caretLink: CaretLinkModel?
|
||||||
public var headlineBody: HeadlineBodyModel
|
public var headlineBody: HeadlineBodyModel
|
||||||
public var image: ImageViewModel
|
public var image: ImageViewModel
|
||||||
|
|
||||||
|
init(headlineBody: HeadlineBodyModel, image: ImageViewModel) {
|
||||||
|
self.headlineBody = headlineBody
|
||||||
|
self.image = image
|
||||||
|
super.init()
|
||||||
|
setDefaults()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defaults to set
|
||||||
|
func setDefaults() {
|
||||||
|
if useHorizontalMargins == nil {
|
||||||
|
useHorizontalMargins = true
|
||||||
|
}
|
||||||
|
if useVerticalMargins == nil {
|
||||||
|
useVerticalMargins = true
|
||||||
|
}
|
||||||
|
if topMarginPadding == nil {
|
||||||
|
topMarginPadding = PaddingDefault
|
||||||
|
}
|
||||||
|
if bottomMarginPadding == nil {
|
||||||
|
bottomMarginPadding = PaddingDefault
|
||||||
|
}
|
||||||
|
if image.height == nil {
|
||||||
|
image.height = HeadLineBodyCaretLinkImage.heightConstant
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case moleculeName
|
||||||
|
case backgroundColor
|
||||||
|
case headlineBody
|
||||||
|
case image
|
||||||
|
case caretLink
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
|
headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody)
|
||||||
|
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
||||||
|
caretLink = try typeContainer.decodeIfPresent(CaretLinkModel.self, forKey: .caretLink)
|
||||||
|
try super.init(from: decoder)
|
||||||
|
setDefaults()
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func encode(to encoder: Encoder) throws {
|
||||||
|
try super.encode(to: encoder)
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(HeadlineBodyCaretLinkImageModel.identifier, forKey: .moleculeName)
|
||||||
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
|
try container.encode(headlineBody, forKey: .headlineBody)
|
||||||
|
try container.encode(image, forKey: .image)
|
||||||
|
try container.encodeIfPresent(caretLink, forKey: .caretLink)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,6 +44,8 @@ import Foundation
|
|||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Line.self, viewModelClass: LineModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Line.self, viewModelClass: LineModel.self)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: GraphView.self, viewModelClass: CircleProgressModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: GraphView.self, viewModelClass: CircleProgressModel.self)
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self)
|
||||||
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self)
|
||||||
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CheckboxWithLabelView.self, viewModelClass: CheckboxLabelModel.self)
|
||||||
|
|
||||||
// Horizontal Combination Molecules
|
// Horizontal Combination Molecules
|
||||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self)
|
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self)
|
||||||
|
|||||||
@ -54,7 +54,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
open override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
|
open override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
|
||||||
let shouldFinish = super.shouldFinishProcessingLoad(loadObject, error: error)
|
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,
|
||||||
@ -63,7 +63,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
error.pointee = errorObject
|
error.pointee = errorObject
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return shouldFinish
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func newDataBuildScreen() {
|
open override func newDataBuildScreen() {
|
||||||
|
|||||||
@ -60,28 +60,18 @@ extension NSLayoutConstraint.Axis: RawRepresentable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@propertyWrapper
|
extension NSLayoutConstraint.Axis: Codable {
|
||||||
public struct Axis {
|
|
||||||
public var wrappedValue: NSLayoutConstraint.Axis
|
|
||||||
|
|
||||||
public init(wrappedValue value: NSLayoutConstraint.Axis) {
|
|
||||||
self.wrappedValue = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Axis: Codable {
|
|
||||||
public init(from decoder: Decoder) throws {
|
public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.singleValueContainer()
|
let typeContainer = try decoder.singleValueContainer()
|
||||||
let string = try typeContainer.decode(String.self)
|
let string = try typeContainer.decode(String.self)
|
||||||
guard let axis = NSLayoutConstraint.Axis(rawValue: string) else {
|
guard let axis = NSLayoutConstraint.Axis(rawValue: string) else {
|
||||||
throw AxisError.notAnAxis
|
throw AxisError.notAnAxis
|
||||||
}
|
}
|
||||||
wrappedValue = axis
|
self = axis
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
let string = wrappedValue.rawValueString
|
|
||||||
var container = encoder.singleValueContainer()
|
var container = encoder.singleValueContainer()
|
||||||
try container.encode(string)
|
try container.encode(rawValueString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,11 @@ import Foundation
|
|||||||
try container.encode(alignment.rawValueString, forKey: .alignment)
|
try container.encode(alignment.rawValueString, forKey: .alignment)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
enum AlignmentError: Error {
|
||||||
|
case notAnAlignment
|
||||||
|
}
|
||||||
|
|
||||||
extension UIStackView.Alignment: RawRepresentable {
|
extension UIStackView.Alignment: RawRepresentable {
|
||||||
|
|
||||||
init?(rawValue: String) {
|
init?(rawValue: String) {
|
||||||
@ -70,3 +75,19 @@ extension UIStackView.Alignment: RawRepresentable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension UIStackView.Alignment: Codable {
|
||||||
|
public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.singleValueContainer()
|
||||||
|
let string = try typeContainer.decode(String.self)
|
||||||
|
guard let alignment = UIStackView.Alignment(rawValue: string) else {
|
||||||
|
throw AlignmentError.notAnAlignment
|
||||||
|
}
|
||||||
|
self = alignment
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.singleValueContainer()
|
||||||
|
try container.encode(rawValueString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user