From 5fd74b695f6b195138db284fa2c0a9c11e1e27cd Mon Sep 17 00:00:00 2001 From: panxi Date: Wed, 20 Nov 2019 14:58:58 -0500 Subject: [PATCH 01/12] create model for progress bar, using ModelMoleculeViewProtocol --- MVMCoreUI.xcodeproj/project.pbxproj | 10 +++- MVMCoreUI/Atoms/Views/MultiProgress.swift | 51 +++++++----------- .../Atoms/Views/MultiProgressModel.swift | 47 +++++++++++++++++ MVMCoreUI/Atoms/Views/ProgressBar.swift | 23 +++++++- MVMCoreUI/Atoms/Views/ProgressBarModel.swift | 52 +++++++++++++++++++ ...UIMoleculeMappingObject+ModelMapping.swift | 2 + 6 files changed, 151 insertions(+), 34 deletions(-) create mode 100644 MVMCoreUI/Atoms/Views/MultiProgressModel.swift create mode 100644 MVMCoreUI/Atoms/Views/ProgressBarModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index cc93db84..1b95a13c 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -46,6 +46,8 @@ 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 */; }; 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 */; }; @@ -260,6 +262,8 @@ 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 = ""; }; 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 = ""; }; @@ -590,6 +594,7 @@ D29DF0CE21E404D4003B2FB9 /* MVMCoreUI */ = { isa = PBXGroup; children = ( + D29DF10D21E67A70003B2FB9 /* Atoms */, 01509D96232803B200EF99AA /* Models */, D2B18B7D236090D500A9AEDC /* BaseClasses */, 01C74D87224298E2009C25A3 /* FormUIHelpers */, @@ -602,7 +607,6 @@ D22D1F582204D2590077CEC0 /* LegacyControllers */, D29DF10F21E67A7D003B2FB9 /* BaseControllers */, D29DF11E21E6851E003B2FB9 /* TopAlert */, - D29DF10D21E67A70003B2FB9 /* Atoms */, D29DF10E21E67A77003B2FB9 /* Molecules */, D22479902316A9CB003FCCF9 /* Organisms */, D29DF0DF21E418B2003B2FB9 /* Templates */, @@ -789,10 +793,12 @@ 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 */, DBC4391722442197001AB423 /* DashLine.swift */, DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */, @@ -1143,6 +1149,7 @@ 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 */, D29DF2C521E7BF57003B2FB9 /* MFTabBarSwipeAnimator.m in Sources */, D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */, @@ -1197,6 +1204,7 @@ 01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.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 */, diff --git a/MVMCoreUI/Atoms/Views/MultiProgress.swift b/MVMCoreUI/Atoms/Views/MultiProgress.swift index fe902d9f..0e911e37 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: MFView { ///passing value to progressList creates corresponding progress bars - var progressList: Array? { + var progressList: Array? { didSet { for subview in subviews { subview.removeFromSuperview() @@ -46,14 +21,18 @@ import UIKit } var previous: UIView? for progressObject in progressList! { - guard progressObject.progress > 0.0 else { + guard progressObject.progress ?? 0.0 > 0.0 else { continue } let view = MFView(frame: .zero) view.translatesAutoresizingMaskIntoConstraints = false addSubview(view) - view.backgroundColor = progressObject.color - view.widthAnchor.constraint(equalTo: widthAnchor, multiplier: progressObject.progress).isActive = true + var color = UIColor.mfCerulean() + if let colorString = progressObject.color { + color = UIColor.mfGet(forHex: colorString) + } + view.backgroundColor = color + view.widthAnchor.constraint(equalTo: widthAnchor, multiplier: progressObject.progress ?? 0).isActive = true view.leadingAnchor.constraint(equalTo: previous?.trailingAnchor ?? leadingAnchor).isActive = true previous = view NSLayoutConstraint.constraintPinSubview(view, pinTop: true, pinBottom: true, pinLeft: false, pinRight: false) @@ -70,6 +49,7 @@ import UIKit } } } + var thicknessConstraint: NSLayoutConstraint? let defaultHeight: CGFloat = 8 @@ -84,6 +64,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 +84,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..156f71a0 --- /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.decodeIfPresent([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..b48f0321 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/ProgressBarModel.swift @@ -0,0 +1,52 @@ +// +// 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.decodeIfPresent(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/MVMCoreUIMoleculeMappingObject+ModelMapping.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift index 67d3df02..a4961b53 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift @@ -18,5 +18,7 @@ import Foundation ModelRegistry.register(ListItemModel.self) ModelRegistry.register(TextFieldModel.self) ModelRegistry.register(LineModel.self) + ModelRegistry.register(ProgressBarModel.self) + ModelRegistry.register(MultiProgressBarModel.self) } } From dde5f1d1a474760591ae632b80aec44e7a38b312 Mon Sep 17 00:00:00 2001 From: panxi Date: Wed, 20 Nov 2019 15:30:42 -0500 Subject: [PATCH 02/12] add caret view model and dash line model --- MVMCoreUI.xcodeproj/project.pbxproj | 8 +++++++ MVMCoreUI/Atoms/Views/CaretView.swift | 24 ++++++++++++++++++- MVMCoreUI/Atoms/Views/CaretViewModel.swift | 19 +++++++++++++++ MVMCoreUI/Atoms/Views/DashLine.swift | 17 ++++++++++++- MVMCoreUI/Atoms/Views/DashLineModel.swift | 18 ++++++++++++++ ...UIMoleculeMappingObject+ModelMapping.swift | 2 ++ 6 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 MVMCoreUI/Atoms/Views/CaretViewModel.swift create mode 100644 MVMCoreUI/Atoms/Views/DashLineModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 1b95a13c..632682a3 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -48,6 +48,8 @@ 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 */; }; 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 */; }; @@ -264,6 +266,8 @@ 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 = ""; }; 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 = ""; }; @@ -800,7 +804,9 @@ 948DB67D2326DCD90011F916 /* MultiProgress.swift */, 9445890D2385C3F800DE9FD4 /* MultiProgressModel.swift */, DBC4391622442196001AB423 /* CaretView.swift */, + 9445891E2385D2E900DE9FD4 /* CaretViewModel.swift */, DBC4391722442197001AB423 /* DashLine.swift */, + 944589202385D6E900DE9FD4 /* DashLineModel.swift */, DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */, D29DF17E21E69E2E003B2FB9 /* MFView.h */, D29DF17F21E69E2E003B2FB9 /* MFView.m */, @@ -1151,6 +1157,7 @@ 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 */, D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */, 01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */, @@ -1200,6 +1207,7 @@ D29DF2BF21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.m in Sources */, D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */, D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationController.m in Sources */, + 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, 01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Views/CaretView.swift b/MVMCoreUI/Atoms/Views/CaretView.swift index ec4457c2..232f4a75 100644 --- a/MVMCoreUI/Atoms/Views/CaretView.swift +++ b/MVMCoreUI/Atoms/Views/CaretView.swift @@ -8,7 +8,8 @@ // -open class CaretView: MFView { +open class CaretView: MFView, ModelMoleculeViewProtocol { + //------------------------------------------------------ // MARK: - Properties //------------------------------------------------------ @@ -132,4 +133,25 @@ open class CaretView: MFView { open override func alignment() -> UIStackView.Alignment { return UIStackView.Alignment.leading; } + + 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 + } + } } 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 512b48cd..3b0cddb2 100644 --- a/MVMCoreUI/Atoms/Views/DashLine.swift +++ b/MVMCoreUI/Atoms/Views/DashLine.swift @@ -10,12 +10,13 @@ import MVMCore -open class DashLine: MFView { +open class DashLine: MFView, ModelMoleculeViewProtocol { //------------------------------------------------------ // MARK: - Properties //------------------------------------------------------ @objc public var dashColor: UIColor? + @objc public var dashLayer: CAShapeLayer? //------------------------------------------------------ // MARK: - Lifecycle @@ -55,6 +56,7 @@ open class DashLine: MFView { dashLayer.strokeColor = dashColor?.cgColor ?? UIColor.mfLighterGray().cgColor dashLayer.fillColor = UIColor.clear.cgColor dashLayer.backgroundColor = backgroundColor?.cgColor ?? UIColor.white.cgColor + self.dashLayer = dashLayer } //------------------------------------------------------ @@ -82,4 +84,17 @@ open class DashLine: MFView { dashColor = UIColor.mfGet(forHex: dashColorHex) } } + + public 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/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift index a4961b53..5cf3168f 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift @@ -20,5 +20,7 @@ import Foundation ModelRegistry.register(LineModel.self) ModelRegistry.register(ProgressBarModel.self) ModelRegistry.register(MultiProgressBarModel.self) + ModelRegistry.register(CaretViewModel.self) + ModelRegistry.register(DashLineModel.self) } } From 28a04218f9afd0824d453c2cff22c9638c9ea02a Mon Sep 17 00:00:00 2001 From: panxi Date: Wed, 20 Nov 2019 15:43:26 -0500 Subject: [PATCH 03/12] create image model --- MVMCoreUI.xcodeproj/project.pbxproj | 4 +++ MVMCoreUI/Atoms/Views/ImageViewModel.swift | 21 ++++++++++++++++ MVMCoreUI/Atoms/Views/MFLoadImageView.swift | 27 ++++++++++++++++++++- 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 MVMCoreUI/Atoms/Views/ImageViewModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 632682a3..67dd46b8 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -50,6 +50,7 @@ 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 */; }; @@ -268,6 +269,7 @@ 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 = ""; }; @@ -816,6 +818,7 @@ D29DF28821E7AC2B003B2FB9 /* ViewConstrainingView.m */, D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */, D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */, + 944589222385DA9500DE9FD4 /* ImageViewModel.swift */, D29DF2AD21E7B3A4003B2FB9 /* MFTextView.h */, D29DF2AB21E7B3A4003B2FB9 /* MFTextView.m */, D29DF2AC21E7B3A4003B2FB9 /* MFTextView.xib */, @@ -1177,6 +1180,7 @@ 01EB369223609801006832FA /* MoleculeStackModel.swift in Sources */, D29DF25421E6A177003B2FB9 /* MFMdnTextField.m in Sources */, D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */, + 944589232385DA9600DE9FD4 /* ImageViewModel.swift in Sources */, D2A514672213885800345BFB /* StandardHeaderView.swift in Sources */, 01EB369023609801006832FA /* ListItemModel.swift in Sources */, DBEFFA04225A829700230692 /* Label.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Views/ImageViewModel.swift b/MVMCoreUI/Atoms/Views/ImageViewModel.swift new file mode 100644 index 00000000..7133e593 --- /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 = "imageView" + 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/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 From 715b5f01674f29b1c607a6631e8efa49c2f068ae Mon Sep 17 00:00:00 2001 From: panxi Date: Wed, 20 Nov 2019 15:48:14 -0500 Subject: [PATCH 04/12] add image, move label model next to label --- MVMCoreUI.xcodeproj/project.pbxproj | 2 +- MVMCoreUI/Atoms/Views/ImageViewModel.swift | 2 +- MVMCoreUI/{Models/Molecules => Atoms/Views}/LabelModel.swift | 0 .../MVMCoreUIMoleculeMappingObject+ModelMapping.swift | 1 + 4 files changed, 3 insertions(+), 2 deletions(-) rename MVMCoreUI/{Models/Molecules => Atoms/Views}/LabelModel.swift (100%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 67dd46b8..5c000157 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -487,7 +487,6 @@ 01EB368723609801006832FA /* Molecules */ = { isa = PBXGroup; children = ( - 01EB368823609801006832FA /* LabelModel.swift */, 01EB368923609801006832FA /* ListItemModel.swift */, 01EB368A23609801006832FA /* MoleculeStackItemModel.swift */, 01EB368B23609801006832FA /* MoleculeStackModel.swift */, @@ -838,6 +837,7 @@ D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */, DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */, DB891E822253FA8500022516 /* Label.swift */, + 01EB368823609801006832FA /* LabelModel.swift */, 0198F7A02256A80A0066C936 /* MFRadioButton.h */, 0198F7A22256A80A0066C936 /* MFRadioButton.m */, 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */, diff --git a/MVMCoreUI/Atoms/Views/ImageViewModel.swift b/MVMCoreUI/Atoms/Views/ImageViewModel.swift index 7133e593..2c9a6dd4 100644 --- a/MVMCoreUI/Atoms/Views/ImageViewModel.swift +++ b/MVMCoreUI/Atoms/Views/ImageViewModel.swift @@ -9,7 +9,7 @@ import Foundation @objcMembers public class ImageViewModel: MoleculeProtocol { - public static var identifier: String = "imageView" + public static var identifier: String = "image" public var moleculeName: String public var image: String diff --git a/MVMCoreUI/Models/Molecules/LabelModel.swift b/MVMCoreUI/Atoms/Views/LabelModel.swift similarity index 100% rename from MVMCoreUI/Models/Molecules/LabelModel.swift rename to MVMCoreUI/Atoms/Views/LabelModel.swift diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift index 5cf3168f..1efebf77 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift @@ -22,5 +22,6 @@ import Foundation ModelRegistry.register(MultiProgressBarModel.self) ModelRegistry.register(CaretViewModel.self) ModelRegistry.register(DashLineModel.self) + ModelRegistry.register(ImageViewModel.self) } } From 6303c3f92ddc042dcb34e9307af5ca2fbdf66e66 Mon Sep 17 00:00:00 2001 From: panxi Date: Thu, 21 Nov 2019 13:15:27 -0500 Subject: [PATCH 05/12] update label model --- MVMCoreUI.xcodeproj/project.pbxproj | 14 ++- MVMCoreUI/Atoms/Views/Label.swift | 117 +++++++++++++++++- MVMCoreUI/Atoms/Views/LabelModel.swift | 16 --- .../LabelModel/LabelAttributeModel.swift | 64 ++++++++++ .../Atoms/Views/LabelModel/LabelModel.swift | 27 ++++ MVMCoreUI/Atoms/Views/MultiProgress.swift | 10 +- .../Atoms/Views/MultiProgressModel.swift | 8 +- MVMCoreUI/Atoms/Views/ProgressBarModel.swift | 5 +- 8 files changed, 228 insertions(+), 33 deletions(-) delete mode 100644 MVMCoreUI/Atoms/Views/LabelModel.swift create mode 100644 MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeModel.swift create mode 100644 MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 5c000157..65ff9299 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -54,6 +54,7 @@ 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 */; }; D206997721FB8A0B00CAE0DE /* MVMCoreUINavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; }; D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = D206997621FB8A0B00CAE0DE /* MVMCoreUINavigationController.m */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; @@ -273,6 +274,7 @@ 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 = ""; }; D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUINavigationController.h; sourceTree = ""; }; D206997621FB8A0B00CAE0DE /* MVMCoreUINavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUINavigationController.m; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; @@ -507,6 +509,15 @@ path = Extensions; sourceTree = ""; }; + 94C2D9822386F3E30006CF46 /* LabelModel */ = { + isa = PBXGroup; + children = ( + 01EB368823609801006832FA /* LabelModel.swift */, + 94C2D9832386F3F80006CF46 /* LabelAttributeModel.swift */, + ); + path = LabelModel; + sourceTree = ""; + }; D224798823142BF2003FCCF9 /* SwitchMolecules */ = { isa = PBXGroup; children = ( @@ -837,7 +848,7 @@ D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */, DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */, DB891E822253FA8500022516 /* Label.swift */, - 01EB368823609801006832FA /* LabelModel.swift */, + 94C2D9822386F3E30006CF46 /* LabelModel */, 0198F7A02256A80A0066C936 /* MFRadioButton.h */, 0198F7A22256A80A0066C936 /* MFRadioButton.m */, 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */, @@ -1210,6 +1221,7 @@ D274CA332236A78900B01B62 /* StandardFooterView.swift in Sources */, D29DF2BF21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.m in Sources */, D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */, + 94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */, D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationController.m in Sources */, 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index 6b013f82..2cd23405 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 //------------------------------------------------------ @@ -212,8 +213,120 @@ 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 as? CGFloat + 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 { + guard let attributeStyle = attribute.type, let location = attribute.location, let length = attribute.length else { continue } + let range = NSRange(location: location, length: length) + switch attributeStyle { + case .underline: + attributedString.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range) + case .strikethrough: + attributedString.addAttribute(.strikethroughStyle, value: NSUnderlineStyle.thick.rawValue, range: range) + attributedString.addAttribute(.baselineOffset, value: 0, range: range) + case .color: + if let colorHex = attribute.textColor, !colorHex.isEmpty { + attributedString.removeAttribute(.foregroundColor, range: range) + attributedString.addAttribute(.foregroundColor, value: UIColor.mfGet(forHex: colorHex), range: range) + } + case .image: + var fontSize = font.pointSize + if let attributeSize = attribute.size { + fontSize = attributeSize + } + let imageName = attribute.name ?? "externalLink" + let imageAttachment: NSTextAttachment + + if let url = attribute.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: location) + case .font: + if let fontStyle = attribute.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 = attribute.size + var font: UIFont? + + if let fontName = attribute.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 .action: + addActionAttributes(range: range, string: attributedString) +// if let actionBlock = createActionBlockFor(actionMap: attribute, additionalData: additionalData, delegateObject: delegateObject) { +// appendActionableClause(range: range, actionBlock: actionBlock) +// } + default: + continue + } + } + } + + originalAttributedString = attributedText + hero = labelModel.hero + } + @objc public static func setUILabel(_ label: UILabel?, withJSON json: [AnyHashable: Any]?, delegate: DelegateObject?, additionalData: [AnyHashable: Any]?) { - //LabelModel() + guard let label = label else { return } label.attributedText = nil label.text = json?.optionalStringForKey(KeyText) diff --git a/MVMCoreUI/Atoms/Views/LabelModel.swift b/MVMCoreUI/Atoms/Views/LabelModel.swift deleted file mode 100644 index e5de1ccf..00000000 --- a/MVMCoreUI/Atoms/Views/LabelModel.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// 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? -} diff --git a/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeModel.swift b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeModel.swift new file mode 100644 index 00000000..e4388ea5 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeModel.swift @@ -0,0 +1,64 @@ +// +// LabelAttributeModel.swift +// MVMCoreUI +// +// Created by Ryan on 11/21/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class LabelAttributeModel: Codable { + enum ModelType: String, Codable { + case underline + case strikethrough + case color + case image + case font + case action + } + + var type: ModelType? + var location: Int? + var length: Int? + var textColor: String? + var style: String? + var size: CGFloat? + var name: String? + var URL: String? + + enum CodingKeys: String, CodingKey { + case type + case location + case length + case textColor + case style + case size + case name + case URL + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + self.type = try typeContainer.decodeIfPresent(ModelType.self, forKey: .type) + self.location = try typeContainer.decodeIfPresent(Int.self, forKey: .location) + self.length = try typeContainer.decodeIfPresent(Int.self, forKey: .length) + self.textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor) + self.style = try typeContainer.decodeIfPresent(String.self, forKey: .style) + 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) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encodeIfPresent(type, forKey: .type) + try container.encodeIfPresent(location, forKey: .location) + try container.encodeIfPresent(length, forKey: .length) + try container.encodeIfPresent(textColor, forKey: .textColor) + try container.encodeIfPresent(style, forKey: .style) + 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/LabelModel.swift b/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift new file mode 100644 index 00000000..376166ed --- /dev/null +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift @@ -0,0 +1,27 @@ +// +// 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? +} diff --git a/MVMCoreUI/Atoms/Views/MultiProgress.swift b/MVMCoreUI/Atoms/Views/MultiProgress.swift index 0e911e37..f6809e53 100644 --- a/MVMCoreUI/Atoms/Views/MultiProgress.swift +++ b/MVMCoreUI/Atoms/Views/MultiProgress.swift @@ -21,18 +21,14 @@ import UIKit } var previous: UIView? for progressObject in progressList! { - guard progressObject.progress ?? 0.0 > 0.0 else { + guard progressObject.progress > 0.0 else { continue } let view = MFView(frame: .zero) view.translatesAutoresizingMaskIntoConstraints = false addSubview(view) - var color = UIColor.mfCerulean() - if let colorString = progressObject.color { - color = UIColor.mfGet(forHex: colorString) - } - view.backgroundColor = color - view.widthAnchor.constraint(equalTo: widthAnchor, multiplier: progressObject.progress ?? 0).isActive = true + 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 NSLayoutConstraint.constraintPinSubview(view, pinTop: true, pinBottom: true, pinLeft: false, pinRight: false) diff --git a/MVMCoreUI/Atoms/Views/MultiProgressModel.swift b/MVMCoreUI/Atoms/Views/MultiProgressModel.swift index 156f71a0..d63183e4 100644 --- a/MVMCoreUI/Atoms/Views/MultiProgressModel.swift +++ b/MVMCoreUI/Atoms/Views/MultiProgressModel.swift @@ -10,14 +10,14 @@ import Foundation @objcMembers public class SingleProgressBarModel: Codable { - var progress: CGFloat? - var color: String? + 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 progressList: [SingleProgressBarModel] public var thickness: CGFloat? public var roundedRect: Bool? @@ -32,7 +32,7 @@ import Foundation let typeContainer = try decoder.container(keyedBy: CodingKeys.self) self.moleculeName = try typeContainer.decode(String.self, forKey: .moleculeName) - self.progressList = try typeContainer.decodeIfPresent([SingleProgressBarModel].self, forKey: .progressList) + 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) } diff --git a/MVMCoreUI/Atoms/Views/ProgressBarModel.swift b/MVMCoreUI/Atoms/Views/ProgressBarModel.swift index b48f0321..3450fc87 100644 --- a/MVMCoreUI/Atoms/Views/ProgressBarModel.swift +++ b/MVMCoreUI/Atoms/Views/ProgressBarModel.swift @@ -15,7 +15,7 @@ import Foundation public var isRounded: Bool? public var thickness: CGFloat? ///from 0 to 100 - public var percentage: Float? + public var percentage: Float public var progressColor: String? public var backgroundColor: String? @@ -29,12 +29,11 @@ import Foundation } 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.decodeIfPresent(Float.self, forKey: .percentage) + 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) From 9ec661ae3b58dac0ecd7aa8a67a74745a14928b3 Mon Sep 17 00:00:00 2001 From: panxi Date: Fri, 22 Nov 2019 14:31:17 -0500 Subject: [PATCH 06/12] add label model --- MVMCoreUI.xcodeproj/project.pbxproj | 24 +++++++ MVMCoreUI/Atoms/Views/Label.swift | 4 +- .../LabelAttributeActionModel.swift | 23 +++++++ .../LabelModel/LabelAttributeColorModel.swift | 35 ++++++++++ .../LabelModel/LabelAttributeFontModel.swift | 33 +++++++++ .../LabelModel/LabelAttributeImageModel.swift | 42 +++++++++++ .../LabelModel/LabelAttributeModel.swift | 53 ++++---------- .../LabelAttributeStrikeThroughModel.swift | 22 ++++++ .../LabelAttributeUnderlineModel.swift | 23 +++++++ .../Atoms/Views/LabelModel/LabelModel.swift | 69 +++++++++++++++++++ ...UIMoleculeMappingObject+ModelMapping.swift | 6 ++ 11 files changed, 294 insertions(+), 40 deletions(-) create mode 100644 MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeActionModel.swift create mode 100644 MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeColorModel.swift create mode 100644 MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeFontModel.swift create mode 100644 MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeImageModel.swift create mode 100644 MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeStrikeThroughModel.swift create mode 100644 MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeUnderlineModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 65ff9299..e9c650c8 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -55,6 +55,12 @@ 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 */; }; D206997721FB8A0B00CAE0DE /* MVMCoreUINavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; }; D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = D206997621FB8A0B00CAE0DE /* MVMCoreUINavigationController.m */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; @@ -275,6 +281,12 @@ 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 = ""; }; D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUINavigationController.h; sourceTree = ""; }; D206997621FB8A0B00CAE0DE /* MVMCoreUINavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUINavigationController.m; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; @@ -514,6 +526,12 @@ 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 = ""; @@ -1150,6 +1168,7 @@ DBC4391822442197001AB423 /* CaretView.swift in Sources */, D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */, D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */, + 94C2D9A923872E5E0006CF46 /* LabelAttributeImageModel.swift in Sources */, DBC4391922442197001AB423 /* DashLine.swift in Sources */, 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */, D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */, @@ -1184,9 +1203,11 @@ D2A5145F2211DDC100345BFB /* MoleculeStackView.swift in Sources */, D29DF27621E79E81003B2FB9 /* MVMCoreUILoggingHandler.m in Sources */, D29DF24D21E6A177003B2FB9 /* MFTextField.m 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 */, D29DF25421E6A177003B2FB9 /* MFMdnTextField.m in Sources */, @@ -1217,6 +1238,7 @@ D29DF18321E69E54003B2FB9 /* SeparatorView.m in Sources */, D29DF17A21E69E1F003B2FB9 /* MFCustomButton.m in Sources */, 017BEB7B236763000024EF95 /* LineModel.swift in Sources */, + 94C2D9A523872C350006CF46 /* LabelAttributeFontModel.swift in Sources */, 017BEB7F23676E870024EF95 /* MVMCoreUIMoleculeMappingObject+ModelMapping.swift in Sources */, D274CA332236A78900B01B62 /* StandardFooterView.swift in Sources */, D29DF2BF21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.m in Sources */, @@ -1251,6 +1273,7 @@ D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */, 01EB369323609801006832FA /* HeaderModel.swift in Sources */, D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */, + 94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */, D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */, D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */, 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */, @@ -1258,6 +1281,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 */, D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */, D29DF25121E6A177003B2FB9 /* MFDigitTextBox.m in Sources */, diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index 2cd23405..c442fbc1 100644 --- a/MVMCoreUI/Atoms/Views/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -260,7 +260,7 @@ public typealias ActionBlock = () -> () 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 { + /*for attribute in attributes { guard let attributeStyle = attribute.type, let location = attribute.location, let length = attribute.length else { continue } let range = NSRange(location: location, length: length) switch attributeStyle { @@ -318,7 +318,7 @@ public typealias ActionBlock = () -> () default: continue } - } + }*/ } originalAttributedString = attributedText 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..992cce53 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeFontModel.swift @@ -0,0 +1,33 @@ +// +// 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? + + private enum CodingKeys: String, CodingKey { + case style + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + self.style = try typeContainer.decodeIfPresent(String.self, forKey: .style) + 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) + } +} 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 index e4388ea5..ae2768ab 100644 --- a/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeModel.swift +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeModel.swift @@ -8,57 +8,34 @@ import Foundation -@objcMembers open class LabelAttributeModel: Codable { - enum ModelType: String, Codable { - case underline - case strikethrough - case color - case image - case font - case action +@objcMembers open class LabelAttributeModel: Model { + + public class var identifier: String { + return "" } - var type: ModelType? - var location: Int? - var length: Int? - var textColor: String? - var style: String? - var size: CGFloat? - var name: String? - var URL: String? + var type: String + var location: Int + var length: Int - enum CodingKeys: String, CodingKey { + private enum CodingKeys: String, CodingKey { case type case location case length - case textColor - case style - case size - case name - case URL } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - self.type = try typeContainer.decodeIfPresent(ModelType.self, forKey: .type) - self.location = try typeContainer.decodeIfPresent(Int.self, forKey: .location) - self.length = try typeContainer.decodeIfPresent(Int.self, forKey: .length) - self.textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor) - self.style = try typeContainer.decodeIfPresent(String.self, forKey: .style) - 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) + 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.encodeIfPresent(type, forKey: .type) - try container.encodeIfPresent(location, forKey: .location) - try container.encodeIfPresent(length, forKey: .length) - try container.encodeIfPresent(textColor, forKey: .textColor) - try container.encodeIfPresent(style, forKey: .style) - try container.encodeIfPresent(size, forKey: .size) - try container.encodeIfPresent(name, forKey: .name) - try container.encodeIfPresent(URL, forKey: .URL) + 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 index 376166ed..e47a395f 100644 --- a/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift @@ -24,4 +24,73 @@ import Foundation 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) + do { + var attributesContainer = try typeContainer.nestedUnkeyedContainer(forKey: .attributes) + var attributes = [LabelAttributeModel]() + while !attributesContainer.isAtEnd { + guard let attmodel = try attributesContainer.decodeUnKeyedIfPresent(LabelAttributeModel.self, typeCodingKey: AttributeTypeKey.type) else { + continue + } + attributes.append(attmodel) + } + self.attributes = attributes + } catch { + print("no attributes") + } + 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/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift index 1efebf77..0dfbae0a 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelMapping.swift @@ -23,5 +23,11 @@ import Foundation 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) } } From ea69ba67ea2ef2b5899ffc3e72e69bfbf2470c3e Mon Sep 17 00:00:00 2001 From: panxi Date: Sun, 24 Nov 2019 23:14:25 -0500 Subject: [PATCH 07/12] update array decoding method --- .../LabelModel/LabelAttributeFontModel.swift | 8 +++++ .../Atoms/Views/LabelModel/LabelModel.swift | 29 ++++++++++--------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeFontModel.swift b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeFontModel.swift index 992cce53..88ae728d 100644 --- a/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeFontModel.swift +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelAttributeFontModel.swift @@ -14,14 +14,20 @@ import UIKit } 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) } @@ -29,5 +35,7 @@ import UIKit 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/LabelModel.swift b/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift index e47a395f..b4c71153 100644 --- a/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift @@ -56,22 +56,25 @@ import Foundation 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) - do { - var attributesContainer = try typeContainer.nestedUnkeyedContainer(forKey: .attributes) - var attributes = [LabelAttributeModel]() - while !attributesContainer.isAtEnd { - guard let attmodel = try attributesContainer.decodeUnKeyedIfPresent(LabelAttributeModel.self, typeCodingKey: AttributeTypeKey.type) else { - continue - } - attributes.append(attmodel) - } - self.attributes = attributes - } catch { - print("no attributes") - } + 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) + /*if let atts = self.attributes { + for attribute in atts { + switch attribute.type { + case "font": + let afont = attribute as? LabelAttributeFontModel + print("font length\(afont!.length), \(String(describing: afont?.name))") + case "color": + let afont = attribute as? LabelAttributeColorModel + print("font length\(afont!.length), \(String(describing: afont?.textColor))") + default: + print("attribute") + } + + } + } */ } public func encode(to encoder: Encoder) throws { From b53f7e7786196cf39c002168e7b778e61d68debc Mon Sep 17 00:00:00 2001 From: panxi Date: Tue, 26 Nov 2019 13:30:06 -0500 Subject: [PATCH 08/12] update --- MVMCoreUI/Models/Molecules/ListItemModel.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Models/Molecules/ListItemModel.swift b/MVMCoreUI/Models/Molecules/ListItemModel.swift index a903299a..3e340ac8 100644 --- a/MVMCoreUI/Models/Molecules/ListItemModel.swift +++ b/MVMCoreUI/Models/Molecules/ListItemModel.swift @@ -12,9 +12,9 @@ import Foundation public static var identifier: String = "listItem" public var moleculeName: String? public var molecule: MoleculeProtocol? - public var actionMap: ActionMapModel? + public var actionMap: ActionModel? - public init(molecule: MoleculeProtocol?, actionMap: ActionMapModel?) { + public init(molecule: MoleculeProtocol?, actionMap: ActionModel?) { self.molecule = molecule self.actionMap = actionMap self.moleculeName = Self.identifier @@ -30,7 +30,7 @@ import Foundation let typeContainer = try decoder.container(keyedBy: CodingKeys.self) self.moleculeName = try typeContainer.decode(String.self, forKey: .moleculeName) self.molecule = try typeContainer.decodeIfPresent(codingKey: .molecule) - self.actionMap = try typeContainer.decodeIfPresent(ActionMapModel.self, forKey: .actionMap) + self.actionMap = try typeContainer.decodeIfPresent(ActionModel.self, forKey: .actionMap) } public func encode(to encoder: Encoder) throws { From 1a5c819a2a224803fbd4a52022467888d14bd030 Mon Sep 17 00:00:00 2001 From: panxi Date: Tue, 26 Nov 2019 13:55:29 -0500 Subject: [PATCH 09/12] fix conflict --- MVMCoreUI/Molecules/StandardHeaderView.swift | 4 ---- 1 file changed, 4 deletions(-) diff --git a/MVMCoreUI/Molecules/StandardHeaderView.swift b/MVMCoreUI/Molecules/StandardHeaderView.swift index 746d510c..e6d00efa 100644 --- a/MVMCoreUI/Molecules/StandardHeaderView.swift +++ b/MVMCoreUI/Molecules/StandardHeaderView.swift @@ -8,11 +8,7 @@ import UIKit -<<<<<<< HEAD -public class StandardHeaderView: ViewConstrainingView { -======= public class StandardHeaderView: ViewConstrainingView, ModelMoleculeViewProtocol { ->>>>>>> feature/models var line: Line? // MARK: - MVMCoreViewProtocol From 269898f56620f0d228ef7ce69f9db7b72ea52640 Mon Sep 17 00:00:00 2001 From: panxi Date: Tue, 26 Nov 2019 13:57:24 -0500 Subject: [PATCH 10/12] fix conflicts --- MVMCoreUI/Atoms/Views/CaretView.swift | 24 +++++++++++++----------- MVMCoreUI/Atoms/Views/DashLine.swift | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/CaretView.swift b/MVMCoreUI/Atoms/Views/CaretView.swift index 08251fcb..2c4669fe 100644 --- a/MVMCoreUI/Atoms/Views/CaretView.swift +++ b/MVMCoreUI/Atoms/Views/CaretView.swift @@ -124,18 +124,8 @@ open class CaretView: View { lineWidth = lineWidthValue } } -} - -extension CaretView: MVMCoreUIViewConstrainingProtocol { - open func needsToBeConstrained() -> Bool { - return true - } - open func alignment() -> UIStackView.Alignment { - return UIStackView.Alignment.leading; - } - - public func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) { + override public func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) { guard let caretModel = model as? CaretViewModel else { return } @@ -156,3 +146,15 @@ extension CaretView: MVMCoreUIViewConstrainingProtocol { } } } + +extension CaretView: MVMCoreUIViewConstrainingProtocol { + open func needsToBeConstrained() -> Bool { + return true + } + + open func alignment() -> UIStackView.Alignment { + return UIStackView.Alignment.leading; + } + + +} diff --git a/MVMCoreUI/Atoms/Views/DashLine.swift b/MVMCoreUI/Atoms/Views/DashLine.swift index 662027fa..937b7313 100644 --- a/MVMCoreUI/Atoms/Views/DashLine.swift +++ b/MVMCoreUI/Atoms/Views/DashLine.swift @@ -84,7 +84,7 @@ open class DashLine: View { } } - public func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) { + public override func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) { guard let dashLineModel = model as? DashLineModel else { return } From 1bbad6ca15cd08413da813a45664b25de0cd4dbb Mon Sep 17 00:00:00 2001 From: panxi Date: Tue, 26 Nov 2019 14:14:53 -0500 Subject: [PATCH 11/12] fix merge conflict --- MVMCoreUI/Atoms/Views/CaretView.swift | 2 - MVMCoreUI/Atoms/Views/Label.swift | 40 +++++++++---------- .../Atoms/Views/LabelModel/LabelModel.swift | 23 ++--------- 3 files changed, 22 insertions(+), 43 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/CaretView.swift b/MVMCoreUI/Atoms/Views/CaretView.swift index 2c4669fe..c02db833 100644 --- a/MVMCoreUI/Atoms/Views/CaretView.swift +++ b/MVMCoreUI/Atoms/Views/CaretView.swift @@ -155,6 +155,4 @@ extension CaretView: MVMCoreUIViewConstrainingProtocol { open func alignment() -> UIStackView.Alignment { return UIStackView.Alignment.leading; } - - } diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index fb9a18a4..f7d476ec 100644 --- a/MVMCoreUI/Atoms/Views/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -259,47 +259,46 @@ public typealias ActionBlock = () -> () 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 { - guard let attributeStyle = attribute.type, let location = attribute.location, let length = attribute.length else { continue } - let range = NSRange(location: location, length: length) - switch attributeStyle { - case .underline: + 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 .strikethrough: + case let strikeAtt as LabelAttributeStrikeThroughModel: attributedString.addAttribute(.strikethroughStyle, value: NSUnderlineStyle.thick.rawValue, range: range) attributedString.addAttribute(.baselineOffset, value: 0, range: range) - case .color: - if let colorHex = attribute.textColor, !colorHex.isEmpty { + 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 .image: + case let imageAtt as LabelAttributeImageModel: var fontSize = font.pointSize - if let attributeSize = attribute.size { + if let attributeSize = imageAtt.size { fontSize = attributeSize } - let imageName = attribute.name ?? "externalLink" + let imageName = imageAtt.name ?? "externalLink" let imageAttachment: NSTextAttachment - if let url = attribute.URL { + 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: location) - case .font: - if let fontStyle = attribute.style { + 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 = attribute.size + let fontSize = fontAtt.size var font: UIFont? - if let fontName = attribute.name { + 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) @@ -309,20 +308,17 @@ public typealias ActionBlock = () -> () attributedString.addAttribute(.font, value: font, range: range) } } - case .action: + case let actionAtt as LabelAttributeActionModel: addActionAttributes(range: range, string: attributedString) -// if let actionBlock = createActionBlockFor(actionMap: attribute, additionalData: additionalData, delegateObject: delegateObject) { -// appendActionableClause(range: range, actionBlock: actionBlock) -// } default: continue } - }*/ } originalAttributedString = attributedText hero = labelModel.hero } + } @objc public static func setUILabel(_ label: UILabel?, withJSON json: [AnyHashable: Any]?, delegate: DelegateObject?, additionalData: [AnyHashable: Any]?) { diff --git a/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift b/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift index b4c71153..cd1c5d12 100644 --- a/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift +++ b/MVMCoreUI/Atoms/Views/LabelModel/LabelModel.swift @@ -60,21 +60,6 @@ import Foundation 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) - /*if let atts = self.attributes { - for attribute in atts { - switch attribute.type { - case "font": - let afont = attribute as? LabelAttributeFontModel - print("font length\(afont!.length), \(String(describing: afont?.name))") - case "color": - let afont = attribute as? LabelAttributeColorModel - print("font length\(afont!.length), \(String(describing: afont?.textColor))") - default: - print("attribute") - } - - } - } */ } public func encode(to encoder: Encoder) throws { @@ -88,10 +73,10 @@ import Foundation 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) -// }) + 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) From 876a07650bccd02479344cdac5ea36d1092604d8 Mon Sep 17 00:00:00 2001 From: panxi Date: Tue, 26 Nov 2019 14:16:12 -0500 Subject: [PATCH 12/12] remove space --- MVMCoreUI/Atoms/Views/Label.swift | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index f7d476ec..388f40cb 100644 --- a/MVMCoreUI/Atoms/Views/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -234,7 +234,6 @@ public typealias ActionBlock = () -> () textAlignment = .left } - makeWholeViewClickable = labelModel.makeWholeViewClickable ?? false if let backgroundColorHex = labelModel.backgroundColor, !backgroundColorHex.isEmpty { backgroundColor = UIColor.mfGet(forHex: backgroundColorHex) @@ -245,7 +244,7 @@ public typealias ActionBlock = () -> () if let fontStyle = labelModel.fontStyle { MFStyler.styleLabel(self, withStyle: fontStyle) } else { - let fontSize = labelModel.fontSize as? CGFloat + let fontSize = labelModel.fontSize if let fontName = labelModel.fontName { font = MFFonts.mfFont(withName: fontName, size: fontSize ?? font.pointSize) } else if let fontSize = fontSize { @@ -313,11 +312,10 @@ public typealias ActionBlock = () -> () default: continue } + } + originalAttributedString = attributedText + hero = labelModel.hero } - - originalAttributedString = attributedText - hero = labelModel.hero - } } @objc public static func setUILabel(_ label: UILabel?, withJSON json: [AnyHashable: Any]?, delegate: DelegateObject?, additionalData: [AnyHashable: Any]?) {