diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index e8de3dd6..f3d044ed 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -62,9 +62,21 @@ 0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; }; 943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; }; 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; }; + 9445890C2385BCE300DE9FD4 /* ProgressBarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */; }; + 9445890E2385C3F800DE9FD4 /* MultiProgressModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445890D2385C3F800DE9FD4 /* MultiProgressModel.swift */; }; + 9445891F2385D2E900DE9FD4 /* CaretViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9445891E2385D2E900DE9FD4 /* CaretViewModel.swift */; }; + 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 944589202385D6E900DE9FD4 /* DashLineModel.swift */; }; + 944589232385DA9600DE9FD4 /* ImageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 944589222385DA9500DE9FD4 /* ImageViewModel.swift */; }; 9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; }; 946EE1BA237B66D80036751F /* ModelHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1B9237B66D80036751F /* ModelHelper.swift */; }; 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; }; + 94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9832386F3F80006CF46 /* LabelAttributeModel.swift */; }; + 94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A023872BCC0006CF46 /* LabelAttributeUnderlineModel.swift */; }; + 94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A223872C110006CF46 /* LabelAttributeStrikeThroughModel.swift */; }; + 94C2D9A523872C350006CF46 /* LabelAttributeFontModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A423872C350006CF46 /* LabelAttributeFontModel.swift */; }; + 94C2D9A723872DA90006CF46 /* LabelAttributeColorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A623872DA90006CF46 /* LabelAttributeColorModel.swift */; }; + 94C2D9A923872E5E0006CF46 /* LabelAttributeImageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A823872E5E0006CF46 /* LabelAttributeImageModel.swift */; }; + 94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9AA23872EB50006CF46 /* LabelAttributeActionModel.swift */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; }; D224798A2314445E003FCCF9 /* LabelSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479892314445E003FCCF9 /* LabelSwitch.swift */; }; @@ -293,9 +305,21 @@ 0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxWithLabelView.swift; sourceTree = ""; }; 943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = ""; }; 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = ""; }; + 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBarModel.swift; sourceTree = ""; }; + 9445890D2385C3F800DE9FD4 /* MultiProgressModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgressModel.swift; sourceTree = ""; }; + 9445891E2385D2E900DE9FD4 /* CaretViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaretViewModel.swift; sourceTree = ""; }; + 944589202385D6E900DE9FD4 /* DashLineModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashLineModel.swift; sourceTree = ""; }; + 944589222385DA9500DE9FD4 /* ImageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageViewModel.swift; sourceTree = ""; }; 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = ""; }; 946EE1B9237B66D80036751F /* ModelHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelHelper.swift; sourceTree = ""; }; 948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = ""; }; + 94C2D9832386F3F80006CF46 /* LabelAttributeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeModel.swift; sourceTree = ""; }; + 94C2D9A023872BCC0006CF46 /* LabelAttributeUnderlineModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeUnderlineModel.swift; sourceTree = ""; }; + 94C2D9A223872C110006CF46 /* LabelAttributeStrikeThroughModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeStrikeThroughModel.swift; sourceTree = ""; }; + 94C2D9A423872C350006CF46 /* LabelAttributeFontModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeFontModel.swift; sourceTree = ""; }; + 94C2D9A623872DA90006CF46 /* LabelAttributeColorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeColorModel.swift; sourceTree = ""; }; + 94C2D9A823872E5E0006CF46 /* LabelAttributeImageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeImageModel.swift; sourceTree = ""; }; + 94C2D9AA23872EB50006CF46 /* LabelAttributeActionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeActionModel.swift; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; D22479892314445E003FCCF9 /* LabelSwitch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelSwitch.swift; sourceTree = ""; }; @@ -528,7 +552,6 @@ isa = PBXGroup; children = ( 012CA98823849699003F810F /* SeperatorModel.swift */, - 01EB368823609801006832FA /* LabelModel.swift */, 01EB368923609801006832FA /* ListItemModel.swift */, 01EB368A23609801006832FA /* MoleculeStackItemModel.swift */, 01EB368B23609801006832FA /* MoleculeStackModel.swift */, @@ -552,6 +575,28 @@ path = Extensions; sourceTree = ""; }; + 94C2D9822386F3E30006CF46 /* LabelModel */ = { + isa = PBXGroup; + children = ( + 01EB368823609801006832FA /* LabelModel.swift */, + 94C2D9832386F3F80006CF46 /* LabelAttributeModel.swift */, + 94C2D9A023872BCC0006CF46 /* LabelAttributeUnderlineModel.swift */, + 94C2D9A223872C110006CF46 /* LabelAttributeStrikeThroughModel.swift */, + 94C2D9A423872C350006CF46 /* LabelAttributeFontModel.swift */, + 94C2D9A623872DA90006CF46 /* LabelAttributeColorModel.swift */, + 94C2D9A823872E5E0006CF46 /* LabelAttributeImageModel.swift */, + 94C2D9AA23872EB50006CF46 /* LabelAttributeActionModel.swift */, + ); + path = LabelModel; + sourceTree = ""; + }; + 94FB5B83238D892800EB2193 /* Recovered References */ = { + isa = PBXGroup; + children = ( + ); + name = "Recovered References"; + sourceTree = ""; + }; D213347423842FE3008E41B3 /* Controllers */ = { isa = PBXGroup; children = ( @@ -652,6 +697,7 @@ D29DF0CE21E404D4003B2FB9 /* MVMCoreUI */, D29DF0CD21E404D4003B2FB9 /* Products */, D29DF0E421E4F3C7003B2FB9 /* Frameworks */, + 94FB5B83238D892800EB2193 /* Recovered References */, ); sourceTree = ""; }; @@ -666,6 +712,7 @@ D29DF0CE21E404D4003B2FB9 /* MVMCoreUI */ = { isa = PBXGroup; children = ( + D29DF10D21E67A70003B2FB9 /* Atoms */, 01509D96232803B200EF99AA /* Models */, D2B18B7D236090D500A9AEDC /* BaseClasses */, 01C74D87224298E2009C25A3 /* FormUIHelpers */, @@ -678,7 +725,6 @@ D22D1F582204D2590077CEC0 /* Legacy */, D29DF10F21E67A7D003B2FB9 /* BaseControllers */, D29DF11E21E6851E003B2FB9 /* TopAlert */, - D29DF10D21E67A70003B2FB9 /* Atoms */, D29DF10E21E67A77003B2FB9 /* Molecules */, D22479902316A9CB003FCCF9 /* Organisms */, D29DF0DF21E418B2003B2FB9 /* Templates */, @@ -865,12 +911,16 @@ isa = PBXGroup; children = ( 01509D922327ECFB00EF99AA /* ProgressBar.swift */, + 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */, D260D7AF22D65BDD007E7233 /* MVMCoreUIPageControl.h */, D260D7B022D65BDD007E7233 /* MVMCoreUIPageControl.m */, D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */, 948DB67D2326DCD90011F916 /* MultiProgress.swift */, + 9445890D2385C3F800DE9FD4 /* MultiProgressModel.swift */, DBC4391622442196001AB423 /* CaretView.swift */, + 9445891E2385D2E900DE9FD4 /* CaretViewModel.swift */, DBC4391722442197001AB423 /* DashLine.swift */, + 944589202385D6E900DE9FD4 /* DashLineModel.swift */, DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */, 012CA99D2385A2D3003F810F /* MFView+ModelExtension.swift */, D29DF28721E7AC2B003B2FB9 /* ViewConstrainingView.h */, @@ -878,6 +928,7 @@ 012CA99B23859FDC003F810F /* ViewConstrainingView+ModelExtension.swift */, D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */, D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */, + 944589222385DA9500DE9FD4 /* ImageViewModel.swift */, D213347623843825008E41B3 /* Line.swift */, D29DF2AD21E7B3A4003B2FB9 /* MFTextView.h */, D29DF2AB21E7B3A4003B2FB9 /* MFTextView.m */, @@ -896,6 +947,7 @@ D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */, DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */, DB891E822253FA8500022516 /* Label.swift */, + 94C2D9822386F3E30006CF46 /* LabelModel */, 0198F7A02256A80A0066C936 /* MFRadioButton.h */, 0198F7A22256A80A0066C936 /* MFRadioButton.m */, 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */, @@ -1198,6 +1250,7 @@ D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */, 012CA9BE2385C692003F810F /* ConstrainingMoleculeProtocol.swift in Sources */, D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */, + 94C2D9A923872E5E0006CF46 /* LabelAttributeImageModel.swift in Sources */, 012CA98923849699003F810F /* SeperatorModel.swift in Sources */, DBC4391922442197001AB423 /* DashLine.swift in Sources */, 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */, @@ -1219,7 +1272,9 @@ DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */, D224798C231450C8003FCCF9 /* HeadlineBodySwitch.swift in Sources */, 017BEB442362192F0024EF95 /* MVMCoreUIMoleculeMappingObject+ModelExtension.swift in Sources */, + 9445890C2385BCE300DE9FD4 /* ProgressBarModel.swift in Sources */, D29DF17C21E69E1F003B2FB9 /* MFTextButton.m in Sources */, + 9445891F2385D2E900DE9FD4 /* CaretViewModel.swift in Sources */, D29DF2C521E7BF57003B2FB9 /* MFTabBarSwipeAnimator.m in Sources */, 012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */, D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */, @@ -1234,14 +1289,17 @@ D29DF27621E79E81003B2FB9 /* MVMCoreUILoggingHandler.m in Sources */, D29DF24D21E6A177003B2FB9 /* MFTextField.m in Sources */, 012A88C4238D86E600FE3DA1 /* CollectionCellMoleculeProtocol.swift in Sources */, + 94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */, 017BEB4023620A230024EF95 /* TextFieldModel.swift in Sources */, D29DF2A221E7AF4E003B2FB9 /* MVMCoreUIUtility.m in Sources */, D29DF12B21E6851E003B2FB9 /* MVMCoreUITopAlertExpandableView.m in Sources */, + 94C2D9A723872DA90006CF46 /* LabelAttributeColorModel.swift in Sources */, D2755D7B23689C7500485468 /* TableViewCell.swift in Sources */, 01EB369223609801006832FA /* MoleculeStackModel.swift in Sources */, 012CA99E2385A2D3003F810F /* MFView+ModelExtension.swift in Sources */, D29DF25421E6A177003B2FB9 /* MFMdnTextField.m in Sources */, D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */, + 944589232385DA9600DE9FD4 /* ImageViewModel.swift in Sources */, D213347723843825008E41B3 /* Line.swift in Sources */, D2A514672213885800345BFB /* StandardHeaderView.swift in Sources */, 01EB369023609801006832FA /* ListItemModel.swift in Sources */, @@ -1271,15 +1329,19 @@ D29DF18321E69E54003B2FB9 /* SeparatorView.m in Sources */, D29DF17A21E69E1F003B2FB9 /* MFCustomButton.m in Sources */, 017BEB7B236763000024EF95 /* LineModel.swift in Sources */, + 94C2D9A523872C350006CF46 /* LabelAttributeFontModel.swift in Sources */, 017BEB7F23676E870024EF95 /* MoleculeObjectMapping.swift in Sources */, D274CA332236A78900B01B62 /* StandardFooterView.swift in Sources */, D29DF2BF21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.m in Sources */, D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */, + 94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */, + 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, 01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, 012A88B1238C880100FE3DA1 /* PagingMoleculeProtocol.swift in Sources */, D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */, + 9445890E2385C3F800DE9FD4 /* MultiProgressModel.swift in Sources */, D2A6390522CBCE160052ED1F /* MoleculeCollectionViewCell.swift in Sources */, D2A6390122CBB1820052ED1F /* Carousel.swift in Sources */, D29DF2C721E7BF57003B2FB9 /* MFTabBarInteractor.m in Sources */, @@ -1306,6 +1368,7 @@ 01EB369323609801006832FA /* HeaderModel.swift in Sources */, D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */, 012A88C6238DA34000FE3DA1 /* ModuleMoleculeModel.swift in Sources */, + 94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */, D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */, D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */, 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */, @@ -1313,6 +1376,7 @@ 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */, D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */, D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */, + 94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */, D29DF26C21E6AA0B003B2FB9 /* FLAnimatedImage.m in Sources */, 012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */, D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */, diff --git a/MVMCoreUI/Atoms/Views/CaretView.swift b/MVMCoreUI/Atoms/Views/CaretView.swift index b68d0535..c02db833 100644 --- a/MVMCoreUI/Atoms/Views/CaretView.swift +++ b/MVMCoreUI/Atoms/Views/CaretView.swift @@ -124,6 +124,27 @@ open class CaretView: View { lineWidth = lineWidthValue } } + + override public func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) { + guard let caretModel = model as? CaretViewModel else { + return + } + if let strokeColorHex = caretModel.strokeColor { + strokeColor = UIColor.mfGet(forHex: strokeColorHex) + } + + if let isHiddenValue = caretModel.isHidden { + isHidden = isHiddenValue + } + + if let isOpaqueValue = caretModel.isOpaque { + isOpaque = isOpaqueValue + } + + if let lineWidthValue = caretModel.lineWidth { + lineWidth = lineWidthValue + } + } } extension CaretView: MVMCoreUIViewConstrainingProtocol { diff --git a/MVMCoreUI/Atoms/Views/CaretViewModel.swift b/MVMCoreUI/Atoms/Views/CaretViewModel.swift new file mode 100644 index 00000000..c0f3ee8c --- /dev/null +++ b/MVMCoreUI/Atoms/Views/CaretViewModel.swift @@ -0,0 +1,19 @@ +// +// CaretViewModel.swift +// MVMCoreUI +// +// Created by Ryan on 11/20/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers public class CaretViewModel: MoleculeProtocol { + public static var identifier: String = "caretView" + public var moleculeName: String + + public var strokeColor: String? + public var isHidden: Bool? + public var isOpaque: Bool? + public var lineWidth: CGFloat? +} diff --git a/MVMCoreUI/Atoms/Views/DashLine.swift b/MVMCoreUI/Atoms/Views/DashLine.swift index 25e39b1b..937b7313 100644 --- a/MVMCoreUI/Atoms/Views/DashLine.swift +++ b/MVMCoreUI/Atoms/Views/DashLine.swift @@ -16,6 +16,7 @@ open class DashLine: View { //------------------------------------------------------ @objc public var dashColor: UIColor? + @objc public var dashLayer: CAShapeLayer? //------------------------------------------------------ // MARK: - Lifecycle @@ -55,6 +56,7 @@ open class DashLine: View { dashLayer.strokeColor = dashColor?.cgColor ?? UIColor.mfLighterGray().cgColor dashLayer.fillColor = UIColor.clear.cgColor dashLayer.backgroundColor = backgroundColor?.cgColor ?? UIColor.white.cgColor + self.dashLayer = dashLayer } //------------------------------------------------------ @@ -81,4 +83,17 @@ open class DashLine: View { dashColor = UIColor.mfGet(forHex: dashColorHex) } } + + public override func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) { + guard let dashLineModel = model as? DashLineModel else { + return + } + dashColor = UIColor.mfGet(forHex: dashLineModel.dashColor) + if let isHiddenValue = dashLineModel.isHidden { + isHidden = isHiddenValue + } + if let backgroundColor = dashLineModel.backgroundColor { + dashLayer?.backgroundColor = UIColor.mfGet(forHex: backgroundColor).cgColor + } + } } diff --git a/MVMCoreUI/Atoms/Views/DashLineModel.swift b/MVMCoreUI/Atoms/Views/DashLineModel.swift new file mode 100644 index 00000000..8fd26fbf --- /dev/null +++ b/MVMCoreUI/Atoms/Views/DashLineModel.swift @@ -0,0 +1,18 @@ +// +// DashLineModel.swift +// MVMCoreUI +// +// Created by Ryan on 11/20/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers public class DashLineModel: MoleculeProtocol { + public static var identifier: String = "dashLine" + public var moleculeName: String + + public var dashColor: String + public var isHidden: Bool? + public var backgroundColor: String? +} diff --git a/MVMCoreUI/Atoms/Views/ImageViewModel.swift b/MVMCoreUI/Atoms/Views/ImageViewModel.swift new file mode 100644 index 00000000..2c9a6dd4 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/ImageViewModel.swift @@ -0,0 +1,21 @@ +// +// ImageViewModel.swift +// MVMCoreUI +// +// Created by Ryan on 11/20/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers public class ImageViewModel: MoleculeProtocol { + public static var identifier: String = "image" + public var moleculeName: String + + public var image: String + public var accessibilityText: String? + public var fallbackImage: String? + public var imageFormat: String? + public var width: CGFloat? + public var height: CGFloat? +} diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index 2f68a8d4..388f40cb 100644 --- a/MVMCoreUI/Atoms/Views/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -12,7 +12,8 @@ import MVMCore public typealias ActionBlock = () -> () -@objcMembers open class Label: UILabel, MVMCoreViewProtocol, MVMCoreUIMoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol, MFButtonProtocol { +@objcMembers open class Label: UILabel, MVMCoreViewProtocol, MVMCoreUIMoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol, MFButtonProtocol, ModelMoleculeViewProtocol { + //------------------------------------------------------ // MARK: - Properties //------------------------------------------------------ @@ -211,6 +212,112 @@ public typealias ActionBlock = () -> () } } + enum LabelAlignment: String { + case center + case right + case left + } + + public func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) { + clauses = [] + guard let labelModel = model as? LabelModel else { return } + attributedText = nil + text = labelModel.text + Label.setLabel(self, withHTML: labelModel.html) + let alignment = LabelAlignment(rawValue: labelModel.textAlignment ?? "") + switch alignment { + case .center: + textAlignment = .center + case .right: + textAlignment = .right + default: + textAlignment = .left + } + + makeWholeViewClickable = labelModel.makeWholeViewClickable ?? false + if let backgroundColorHex = labelModel.backgroundColor, !backgroundColorHex.isEmpty { + backgroundColor = UIColor.mfGet(forHex: backgroundColorHex) + } + if let accessibilityText = labelModel.accessibilityText { + accessibilityLabel = accessibilityText + } + if let fontStyle = labelModel.fontStyle { + MFStyler.styleLabel(self, withStyle: fontStyle) + } else { + let fontSize = labelModel.fontSize + if let fontName = labelModel.fontName { + font = MFFonts.mfFont(withName: fontName, size: fontSize ?? font.pointSize) + } else if let fontSize = fontSize { + font = font.withSize(fontSize) + } + } + + if let textColorHex = labelModel.textColor, !textColorHex.isEmpty { + textColor = UIColor.mfGet(forHex: textColorHex) + } + + if let attributes = labelModel.attributes, let labelText = text { + let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: font as UIFont, NSAttributedString.Key.foregroundColor: textColor as UIColor]) + for attribute in attributes { + let range = NSRange(location: attribute.location, length: attribute.length) + switch attribute { + case let underLineAtt as LabelAttributeUnderlineModel: + attributedString.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range) + case let strikeAtt as LabelAttributeStrikeThroughModel: + attributedString.addAttribute(.strikethroughStyle, value: NSUnderlineStyle.thick.rawValue, range: range) + attributedString.addAttribute(.baselineOffset, value: 0, range: range) + case let colorAtt as LabelAttributeColorModel: + if let colorHex = colorAtt.textColor, !colorHex.isEmpty { + attributedString.removeAttribute(.foregroundColor, range: range) + attributedString.addAttribute(.foregroundColor, value: UIColor.mfGet(forHex: colorHex), range: range) + } + case let imageAtt as LabelAttributeImageModel: + var fontSize = font.pointSize + if let attributeSize = imageAtt.size { + fontSize = attributeSize + } + let imageName = imageAtt.name ?? "externalLink" + let imageAttachment: NSTextAttachment + + if let url = imageAtt.URL { + imageAttachment = Label.getTextAttachmentFrom(url: url, dimension: fontSize, label: self) + } else { + imageAttachment = Label.getTextAttachmentImage(name: imageName, dimension: fontSize) + } + let mutableString = NSMutableAttributedString() + mutableString.append(NSAttributedString(attachment: imageAttachment)) + attributedString.insert(mutableString, at: imageAtt.location) + case let fontAtt as LabelAttributeFontModel: + if let fontStyle = fontAtt.style { + let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle) + attributedString.removeAttribute(.font, range: range) + attributedString.removeAttribute(.foregroundColor, range: range) + attributedString.addAttributes(styles.attributes(at: 0, effectiveRange: nil), range: range) + } else { + let fontSize = fontAtt.size + var font: UIFont? + + if let fontName = fontAtt.name { + font = MFFonts.mfFont(withName: fontName, size: fontSize ?? self.font.pointSize) + } else if let fontSize = fontSize { + font = self.font.withSize(fontSize) + } + if let font = font { + attributedString.removeAttribute(.font, range: range) + attributedString.addAttribute(.font, value: font, range: range) + } + } + case let actionAtt as LabelAttributeActionModel: + addActionAttributes(range: range, string: attributedString) + default: + continue + } + } + originalAttributedString = attributedText + hero = labelModel.hero + } + } + @objc public static func setUILabel(_ label: UILabel?, withJSON json: [AnyHashable: Any]?, delegate: DelegateObject?, additionalData: [AnyHashable: Any]?) { guard let label = label else { return } diff --git a/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeActionModel.swift b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeActionModel.swift new file mode 100644 index 00000000..eb5a3cd7 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeActionModel.swift @@ -0,0 +1,23 @@ +// +// LabelAttributeActionModel.swift +// MVMCoreUI +// +// Created by Ryan on 11/21/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +class LabelAttributeActionModel: LabelAttributeModel { + override public class var identifier: String { + return "action" + } + + required public init(from decoder: Decoder) throws { + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + } +} diff --git a/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeColorModel.swift b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeColorModel.swift new file mode 100644 index 00000000..26f1fa54 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeColorModel.swift @@ -0,0 +1,35 @@ +// +// LabelAttributeColorModel.swift +// MVMCoreUI +// +// Created by Ryan on 11/21/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers public class LabelAttributeColorModel: LabelAttributeModel { + + override public class var identifier: String { + return "color" + } + + var textColor: String? + + private enum CodingKeys: String, CodingKey { + case textColor + } + + required public init(from decoder: Decoder) throws { + + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + self.textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encodeIfPresent(textColor, forKey: .textColor) + } +} diff --git a/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeFontModel.swift b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeFontModel.swift new file mode 100644 index 00000000..88ae728d --- /dev/null +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeFontModel.swift @@ -0,0 +1,41 @@ +// +// LabelAttributeFontModel.swift +// MVMCoreUI +// +// Created by Ryan on 11/21/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers public class LabelAttributeFontModel: LabelAttributeModel { + override public class var identifier: String { + return "font" + } + + var style: String? + var name: String? + var size: CGFloat? + + private enum CodingKeys: String, CodingKey { + case style + case name + case size + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + self.style = try typeContainer.decodeIfPresent(String.self, forKey: .style) + self.name = try typeContainer.decodeIfPresent(String.self, forKey: .name) + self.size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encodeIfPresent(style, forKey: .style) + try container.encodeIfPresent(name, forKey: .name) + try container.encodeIfPresent(size, forKey: .size) + } +} diff --git a/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeImageModel.swift b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeImageModel.swift new file mode 100644 index 00000000..0095a589 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeImageModel.swift @@ -0,0 +1,42 @@ +// +// LabelAttributeImageModel.swift +// MVMCoreUI +// +// Created by Ryan on 11/21/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +class LabelAttributeImageModel: LabelAttributeModel { + + override public class var identifier: String { + return "image" + } + + var size: CGFloat? + var name: String? + var URL: String? + + private enum CodingKeys: String, CodingKey { + case size + case name + case URL + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + self.size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size) + self.name = try typeContainer.decodeIfPresent(String.self, forKey: .name) + self.URL = try typeContainer.decodeIfPresent(String.self, forKey: .URL) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encodeIfPresent(size, forKey: .size) + try container.encodeIfPresent(name, forKey: .name) + try container.encodeIfPresent(URL, forKey: .URL) + } +} diff --git a/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeModel.swift b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeModel.swift new file mode 100644 index 00000000..ae2768ab --- /dev/null +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeModel.swift @@ -0,0 +1,41 @@ +// +// LabelAttributeModel.swift +// MVMCoreUI +// +// Created by Ryan on 11/21/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class LabelAttributeModel: Model { + + public class var identifier: String { + return "" + } + + var type: String + var location: Int + var length: Int + + private enum CodingKeys: String, CodingKey { + case type + case location + case length + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + self.type = try typeContainer.decode(String.self, forKey: .type) + self.location = try typeContainer.decode(Int.self, forKey: .location) + self.length = try typeContainer.decode(Int.self, forKey: .length) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(type, forKey: .type) + try container.encode(location, forKey: .location) + try container.encode(length, forKey: .length) + } + +} diff --git a/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeStrikeThroughModel.swift b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeStrikeThroughModel.swift new file mode 100644 index 00000000..f69e966d --- /dev/null +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeStrikeThroughModel.swift @@ -0,0 +1,22 @@ +// +// LabelAttributeStrikeThroughModel.swift +// MVMCoreUI +// +// Created by Ryan on 11/21/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers public class LabelAttributeStrikeThroughModel: LabelAttributeModel { + override public class var identifier: String { + return "strikethrough" + } + required public init(from decoder: Decoder) throws { + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + } +} diff --git a/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeUnderlineModel.swift b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeUnderlineModel.swift new file mode 100644 index 00000000..d052686d --- /dev/null +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeUnderlineModel.swift @@ -0,0 +1,23 @@ +// +// LabelAttributeUnderlineModel.swift +// MVMCoreUI +// +// Created by Ryan on 11/21/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers public class LabelAttributeUnderlineModel: LabelAttributeModel { + override public class var identifier: String { + return "underline" + } + + required public init(from decoder: Decoder) throws { + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + } +} diff --git a/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift b/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift new file mode 100644 index 00000000..cd1c5d12 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift @@ -0,0 +1,84 @@ +// +// Label.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 10/3/19. +// Copyright © 2019 Suresh, Kamlesh. All rights reserved. +// + + +import Foundation + +@objcMembers public class LabelModel: MoleculeProtocol { + public static var identifier: String = "label" + public var moleculeName: String? + public var text: String + public var accessibilityText: String? + public var textColor: String? + public var backgroundColor: String? + public var fontStyle: String? + public var fontName: String? + public var fontSize: CGFloat? + public var textAlignment: String? + public var attributes: [LabelAttributeModel]? + public var html: String? + public var hero: Int? + public var makeWholeViewClickable: Bool? + + enum CodingKeys: String, CodingKey { + case moleculeName + case text + case accessibilityText + case textColor + case backgroundColor + case fontStyle + case fontName + case fontSize + case textAlignment + case attributes + case html + case hero + case makeWholeViewClickable + } + + enum AttributeTypeKey: String, CodingKey { + case type + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + self.moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName) + self.text = try typeContainer.decode(String.self, forKey: .text) + self.accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) + self.textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor) + self.backgroundColor = try typeContainer.decodeIfPresent(String.self, forKey: .backgroundColor) + self.fontStyle = try typeContainer.decodeIfPresent(String.self, forKey: .fontStyle) + self.fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName) + self.fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize) + self.textAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .textAlignment) + self.attributes = try typeContainer.decodeArrayIfPresent(codingKey: .attributes, typeCodingKey: AttributeTypeKey.type) as? [LabelAttributeModel] + self.html = try typeContainer.decodeIfPresent(String.self, forKey: .html) + self.hero = try typeContainer.decodeIfPresent(Int.self, forKey: .hero) + self.makeWholeViewClickable = try typeContainer.decodeIfPresent(Bool.self, forKey: .makeWholeViewClickable) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encodeIfPresent(moleculeName, forKey: .moleculeName) + try container.encode(text, forKey: .moleculeName) + try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) + try container.encodeIfPresent(textColor, forKey: .textColor) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(fontStyle, forKey: .fontStyle) + try container.encodeIfPresent(fontName, forKey: .fontName) + try container.encodeIfPresent(fontSize, forKey: .fontSize) + try container.encodeIfPresent(textAlignment, forKey: .textAlignment) + var attributeContainer = container.nestedUnkeyedContainer(forKey: .attributes) + try attributes?.forEach({ (attributeModel) in + try attributeContainer.encode(attributeModel) + }) + try container.encodeIfPresent(html, forKey: .html) + try container.encodeIfPresent(hero, forKey: .hero) + try container.encodeIfPresent(makeWholeViewClickable, forKey: .makeWholeViewClickable) + } +} diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift index 361c0aa2..95b00cd7 100644 --- a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift @@ -8,7 +8,7 @@ import UIKit -@objcMembers open class MFLoadImageView: ViewConstrainingView { +@objcMembers open class MFLoadImageView: ViewConstrainingView, ModelMoleculeViewProtocol { public let loadingSpinner = MFLoadingSpinner(frame: .zero) public let imageView = MFTransparentGIFView(frame: .zero) public var addSizeConstraintsForAspectRatio = false @@ -209,6 +209,31 @@ import UIKit } } + public func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) { + guard let imageModel = model as? ImageViewModel else { + return + } + if let accessibilityString = imageModel.accessibilityText { + imageView.accessibilityLabel = accessibilityString + imageView.accessibilityTraits = .staticText + imageView.isAccessibilityElement = true + } + let width = imageModel.width ?? imageWidth + let height = imageModel.height ?? imageHeight + // For smoother transitions, set constraints that we know immediately. + if let width = width, addSizeConstraintsForAspectRatio { + setWidth(width) + } + if let height = height, addSizeConstraintsForAspectRatio { + setHeight(height) + } + if shouldLoadImage(withName: imageModel.image, width: width, height: height) { + imageView.image = nil + imageView.animatedImage = nil + loadImage(withName: imageModel.image, format: imageModel.imageFormat, width: width as NSNumber?, height: height as NSNumber?, customFallbackImage: imageModel.fallbackImage) + } + } + // MARK: - MVMCoreUIMoleculeViewProtocol functions open override func setAsMolecule() { addSizeConstraintsForAspectRatio = true diff --git a/MVMCoreUI/Atoms/Views/MultiProgress.swift b/MVMCoreUI/Atoms/Views/MultiProgress.swift index fdfb5316..6f35bcc5 100644 --- a/MVMCoreUI/Atoms/Views/MultiProgress.swift +++ b/MVMCoreUI/Atoms/Views/MultiProgress.swift @@ -8,35 +8,10 @@ import UIKit -@objcMembers open class ProgressBarObject { - ///from 0.0 to 1.0. input progress should be [0 100] - var progress: CGFloat = 0.0 - ///default color is cerulean - var color: UIColor = UIColor.mfCerulean() +@objcMembers open class MultiProgress: ViewConstrainingView, ModelMoleculeViewProtocol { - init(_ module: [AnyHashable: Any]?) { - progress = (module?.optionalCGFloatForKey("progress") ?? 0.0)/100 - if let colorString = module?.optionalStringForKey("progressColor") { - color = UIColor.mfGet(forHex: colorString) - } - } - - static func getProgressBarObjectList(_ list: [[AnyHashable: Any]]?) -> [ProgressBarObject]? { - guard list?.count ?? 0 > 0 else { - return nil - } - var progressList = [ProgressBarObject]() - for module in list! { - let progressObject = ProgressBarObject(module) - progressList.append(progressObject) - } - return progressList - } -} - -@objcMembers open class MultiProgress: View { ///passing value to progressList creates corresponding progress bars - var progressList: Array? { + var progressList: Array? { didSet { for subview in subviews { subview.removeFromSuperview() @@ -52,7 +27,7 @@ import UIKit let view = UIView(frame: .zero) view.translatesAutoresizingMaskIntoConstraints = false addSubview(view) - view.backgroundColor = progressObject.color + view.backgroundColor = UIColor.mfGet(forHex: progressObject.color) view.widthAnchor.constraint(equalTo: widthAnchor, multiplier: progressObject.progress).isActive = true view.leadingAnchor.constraint(equalTo: previous?.trailingAnchor ?? leadingAnchor).isActive = true previous = view @@ -70,6 +45,7 @@ import UIKit } } } + var thicknessConstraint: NSLayoutConstraint? let defaultHeight: CGFloat = 8 @@ -84,6 +60,16 @@ import UIKit } } + public func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) { + guard let multiProgressModel = model as? MultiProgressBarModel else { + return + } + roundedRect = multiProgressModel.roundedRect ?? false + thicknessConstraint?.constant = multiProgressModel.thickness ?? defaultHeight + progressList = multiProgressModel.progressList + + } + open override func reset() { super.reset() backgroundColor = .mfLightSilver() @@ -94,6 +80,5 @@ import UIKit super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) thicknessConstraint?.constant = json?.optionalCGFloatForKey("thickness") ?? defaultHeight roundedRect = json?.optionalBoolForKey("roundedRect") ?? false - progressList = ProgressBarObject.getProgressBarObjectList(json?.optionalArrayForKey("progressList") as? [[AnyHashable: Any]]) } } diff --git a/MVMCoreUI/Atoms/Views/MultiProgressModel.swift b/MVMCoreUI/Atoms/Views/MultiProgressModel.swift new file mode 100644 index 00000000..d63183e4 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/MultiProgressModel.swift @@ -0,0 +1,47 @@ +// +// MultiProgressModel.swift +// MVMCoreUI +// +// Created by Ryan on 11/20/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import Foundation + + +@objcMembers public class SingleProgressBarModel: Codable { + var progress: CGFloat + var color: String +} + +@objcMembers public class MultiProgressBarModel: MoleculeProtocol { + public static var identifier: String = "multiProgressBar" + public var moleculeName: String + public var progressList: [SingleProgressBarModel] + public var thickness: CGFloat? + public var roundedRect: Bool? + + enum CodingKeys: String, CodingKey { + case moleculeName + case progressList + case thickness + case roundedRect + } + + required public init(from decoder: Decoder) throws { + + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + self.moleculeName = try typeContainer.decode(String.self, forKey: .moleculeName) + self.progressList = try typeContainer.decode([SingleProgressBarModel].self, forKey: .progressList) + self.thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness) + self.roundedRect = try typeContainer.decodeIfPresent(Bool.self, forKey: .roundedRect) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encodeIfPresent(progressList, forKey: .progressList) + try container.encodeIfPresent(thickness, forKey: .thickness) + try container.encodeIfPresent(roundedRect, forKey: .roundedRect) + } +} diff --git a/MVMCoreUI/Atoms/Views/ProgressBar.swift b/MVMCoreUI/Atoms/Views/ProgressBar.swift index 1aecd537..45ce85d6 100644 --- a/MVMCoreUI/Atoms/Views/ProgressBar.swift +++ b/MVMCoreUI/Atoms/Views/ProgressBar.swift @@ -8,7 +8,7 @@ import Foundation -@objcMembers open class ProgressBar: UIProgressView, MVMCoreUIMoleculeViewProtocol, MVMCoreViewProtocol { +@objcMembers open class ProgressBar: UIProgressView, MVMCoreViewProtocol, ModelMoleculeViewProtocol, MVMCoreUIMoleculeViewProtocol { var isRounded = false var thickness: CGFloat = 8.0 { willSet(newValue) { @@ -40,12 +40,31 @@ import Foundation public func setupView() { clipsToBounds = true translatesAutoresizingMaskIntoConstraints = false - reset() + isRounded = false + thickness = 8 + progress = 0 + progressTintColor = UIColor.mfCerulean() + trackTintColor = UIColor.mfLightSilver() } public func updateView(_ size: CGFloat) { } + public func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String: AnyHashable]?) { + guard let progressBarModel = model as? ProgressBarModel else { + return + } + isRounded = progressBarModel.isRounded ?? false + thickness = progressBarModel.thickness ?? 8 + progress = (progressBarModel.percentage ?? 0)/100.0 + if let progressColor = progressBarModel.progressColor { + progressTintColor = UIColor.mfGet(forHex: progressColor) + } + if let backgroundColor = progressBarModel.backgroundColor { + trackTintColor = UIColor.mfGet(forHex: backgroundColor) + } + } + // MARK: - MVMCoreUIMoleculeViewProtocol public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { if let isRounded = json?.optionalBoolForKey("roundedRect") { diff --git a/MVMCoreUI/Atoms/Views/ProgressBarModel.swift b/MVMCoreUI/Atoms/Views/ProgressBarModel.swift new file mode 100644 index 00000000..3450fc87 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/ProgressBarModel.swift @@ -0,0 +1,51 @@ +// +// ProgressBarModel.swift +// MVMCoreUI +// +// Created by Ryan on 11/20/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers public class ProgressBarModel: MoleculeProtocol { + public static var identifier: String = "progressbar" + public var moleculeName: String + + public var isRounded: Bool? + public var thickness: CGFloat? + ///from 0 to 100 + public var percentage: Float + public var progressColor: String? + public var backgroundColor: String? + + enum CodingKeys: String, CodingKey { + case moleculeName + case isRounded = "roundRect" + case thickness + case percentage = "percent" + case progressColor + case backgroundColor + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + self.moleculeName = try typeContainer.decode(String.self, forKey: .moleculeName) + self.isRounded = try typeContainer.decodeIfPresent(Bool.self, forKey: .isRounded) + self.thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness) + self.percentage = try typeContainer.decode(Float.self, forKey: .percentage) + self.progressColor = try typeContainer.decodeIfPresent(String.self, forKey: .progressColor) + self.backgroundColor = try typeContainer.decodeIfPresent(String.self, forKey: .backgroundColor) + + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encodeIfPresent(isRounded, forKey: .isRounded) + try container.encodeIfPresent(thickness, forKey: .thickness) + try container.encodeIfPresent(percentage, forKey: .percentage) + try container.encodeIfPresent(progressColor, forKey: .progressColor) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + } +} diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index 84e0932c..983fac13 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -19,5 +19,16 @@ import Foundation ModelRegistry.register(TextFieldModel.self) ModelRegistry.register(LineModel.self) ModelRegistry.register(SeperatorModel.self) + ModelRegistry.register(ProgressBarModel.self) + ModelRegistry.register(MultiProgressBarModel.self) + ModelRegistry.register(CaretViewModel.self) + ModelRegistry.register(DashLineModel.self) + ModelRegistry.register(ImageViewModel.self) + ModelRegistry.register(LabelAttributeFontModel.self) + ModelRegistry.register(LabelAttributeColorModel.self) + ModelRegistry.register(LabelAttributeImageModel.self) + ModelRegistry.register(LabelAttributeUnderlineModel.self) + ModelRegistry.register(LabelAttributeStrikeThroughModel.self) + ModelRegistry.register(LabelAttributeActionModel.self) } }