From 487d41b3d99a28649f5b17fa0d9cfbd68f917afb Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 31 Jan 2020 16:01:06 -0500 Subject: [PATCH 01/57] two button view update --- .../TwoButtonView.swift | 333 ++++-------------- 1 file changed, 62 insertions(+), 271 deletions(-) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift index 5c80bd1a..9a4f31f9 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -8,11 +8,10 @@ import UIKit -@objcMembers open class TwoButtonView: ViewConstrainingView { - open var primaryButton: PrimaryButton? = PrimaryButton.button() - open var secondaryButton: PrimaryButton? = PrimaryButton.button() - open var viewForButtons: UIView? - public var heightConstraint: NSLayoutConstraint? +@objcMembers open class TwoButtonView: View, MVMCoreUIViewConstrainingProtocol { + open var primaryButton: PillButton = PillButton() + open var secondaryButton: PillButton = PillButton() + private var stack = UIStackView() public init() { super.init(frame: .zero) @@ -26,289 +25,81 @@ import UIKit super.init(frame: frame) } - public func setDefaultCustom() { - primaryButton?.setAsStandardCustom() - secondaryButton?.setAsSecondaryCustom() + public func setDefault() { + primaryButton.stylePrimary() + secondaryButton.styleSecondary() } // MARK: - MVMCoreViewProtocol open override func updateView(_ size: CGFloat) { super.updateView(size) - MVMCoreDispatchUtility.performBlock(onMainThread: { - self.primaryButton?.updateView(size) - self.secondaryButton?.updateView(size) - }) + self.primaryButton.updateView(size) + self.secondaryButton.updateView(size) } open override func setupView() { super.setupView() - setupWithTwoButtons() - secondaryButton?.bordered = true + + stack.translatesAutoresizingMaskIntoConstraints = false + addSubview(stack) + stack.addArrangedSubview(primaryButton) + stack.addArrangedSubview(secondaryButton) + NSLayoutConstraint.constraintPinSubview(toSuperview: stack) + stack.axis = .horizontal + stack.spacing = 10 + } + + // MARK: - Stack Manipulation + public func showPrimaryButton() { + if primaryButton.superview == nil { + stack.addArrangedSubview(primaryButton) + } + } + + public func showSecondaryButton() { + if secondaryButton.superview == nil { + stack.addArrangedSubview(secondaryButton) + } + } + + public func hidePrimaryButton() { + if primaryButton.superview != nil { + stack.removeArrangedSubview(primaryButton) + } + } + + public func hideSecondaryButton() { + if secondaryButton.superview != nil { + stack.removeArrangedSubview(secondaryButton) + } } // MARK: - MVMCoreUIMoleculeViewProtocol - open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - let primaryButtonMap = json?.optionalDictionaryForKey("primaryButton") - let secondaryButtonMap = json?.optionalDictionaryForKey("secondaryButton") - set(primaryButtonJSON: primaryButtonMap, secondaryButtonJSON: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - } - open override func reset() { super.reset() - primaryButton?.setAsStandardCustom() - secondaryButton?.setAsSecondaryCustom() + setDefault() } - - // MARK: - Constraining - func createPrimaryButton() { - if primaryButton == nil { - primaryButton = PrimaryButton.button() - } - } - - func createSecondaryButton() { - if secondaryButton == nil { - secondaryButton = PrimaryButton.button() - secondaryButton?.bordered = true - } - } - - func removeButtons() { - viewForButtons?.removeFromSuperview() - primaryButton?.removeFromSuperview() - secondaryButton?.removeFromSuperview() - viewForButtons = nil - secondaryButton = nil - primaryButton = nil - } - - open func setupConstraintsForViewWithButtons() { - guard let viewForButtons = viewForButtons, - let primaryButton = primaryButton, - let secondaryButton = secondaryButton - else { return } - - viewForButtons.addSubview(primaryButton) - viewForButtons.addSubview(secondaryButton) - secondaryButton.widthAnchor.constraint(equalTo: primaryButton.widthAnchor, multiplier: 1).isActive = true - NSLayoutConstraint.constraintPinSubview(secondaryButton, pinTop: true, pinBottom: true, pinLeft: true, pinRight: false) - NSLayoutConstraint.constraintPinSubview(primaryButton, pinTop: true, pinBottom: true, pinLeft: false, pinRight: true) - let constraint = primaryButton.leadingAnchor.constraint(equalTo: secondaryButton.trailingAnchor, constant: 10) - constraint.priority = UILayoutPriority(900) - constraint.isActive = true - } - - func setupWithTwoButtons() { - guard viewForButtons == nil else { - return - } - let viewForButtons = MVMCoreUICommonViewsUtility.commonView() - addSubview(viewForButtons) - self.viewForButtons = viewForButtons - - pinView(toSuperView: viewForButtons) - alignCenterHorizontal() - createPrimaryButton() - createSecondaryButton() - setupConstraintsForViewWithButtons() - } - - open func setupWithPrimaryButton() { - guard primaryButton == nil && secondaryButton == nil else { - return - } - createPrimaryButton() - if let primaryButton = primaryButton { - addSubview(primaryButton) - pinView(toSuperView: primaryButton) - alignCenterHorizontal() - } - } - - open func setupWithSecondaryButton() { - guard secondaryButton == nil && primaryButton == nil else { - return - } - createSecondaryButton() - if let secondaryButton = secondaryButton { - addSubview(secondaryButton) - pinView(toSuperView: secondaryButton) - alignCenterHorizontal() - } - } - - /// Legacy - func setupUI(withPrimaryButtonMap primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?) { - setupUI(primaryButtonShowing: primaryButtonMap != nil, secondaryButtonShowing: secondaryButtonMap != nil) - } - - func setupUI(primaryButtonShowing: Bool, secondaryButtonShowing: Bool) { - if primaryButtonShowing, secondaryButtonShowing { - heightConstraint?.isActive = false - if primaryButton == nil || secondaryButton == nil { - removeButtons() - setupWithTwoButtons() - } - } else if primaryButtonShowing { - heightConstraint?.isActive = false - if primaryButton == nil || secondaryButton != nil { - removeButtons() - setupWithPrimaryButton() - } - } else if secondaryButtonShowing { - heightConstraint?.isActive = false - if secondaryButton == nil || primaryButton != nil { - removeButtons() - setupWithSecondaryButton() - } - } else { - removeButtons() - if heightConstraint == nil { - heightConstraint = heightAnchor.constraint(equalToConstant: 0) - heightConstraint?.isActive = true - } - } - } - - open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON) - setDefaultCustom() - primaryButton?.setWithJSON(primaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData) - secondaryButton?.setWithJSON(secondaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData) - } - - // MARK: - Legacy - public convenience init(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { - self.init() - setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - } - - public convenience init(buttonSmall small: Bool, buttonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: AnyHashable]?) { - self.init() - setup(withButtonMap: buttonMap, delegateObject: delegateObject, additionalData: additionalData) - primaryButton?.setAsSmall(small) - secondaryButton?.setAsSmall(small) - } - - public convenience init(buttonSmall small: Bool, enabled: Bool) { - self.init() - removeButtons() - setupWithPrimaryButton() - primaryButton?.setAsSmall(small) - primaryButton?.isEnabled = enabled - } - - open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { - setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap) - if primaryButtonMap != nil, secondaryButtonMap != nil { - primaryButton?.setWithActionMap(primaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - secondaryButton?.setWithActionMap(secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - } else if primaryButtonMap != nil { - primaryButton?.setWithActionMap(primaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - primaryButton?.bordered = false - } else if secondaryButtonMap != nil { - secondaryButton?.setWithActionMap(secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - secondaryButton?.bordered = true - } - } - - open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { - let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton) - let primaryButtonMap = buttonMap?.optionalDictionaryForKey(KeyPrimaryButton) - setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) - } - - public func hideLeftButton() { - guard let secondaryButton = secondaryButton, !secondaryButton.isHidden else { - return - } - secondaryButton.isHidden = true - if let primaryButton = primaryButton { - primaryButton.removeFromSuperview() - viewForButtons?.addSubview(primaryButton) - NSLayoutConstraint.constraintPinSubview(toSuperview: primaryButton) - } - } - - public func hideRightButton() { - guard let primaryButton = primaryButton, !primaryButton.isHidden else { - return - } - primaryButton.isHidden = true - if let secondaryButton = secondaryButton { - secondaryButton.removeFromSuperview() - viewForButtons?.addSubview(secondaryButton) - NSLayoutConstraint.constraintPinSubview(toSuperview: secondaryButton) - } - } - - public func showBothButtons() { - primaryButton?.isHidden = false - secondaryButton?.isHidden = false - if let primaryButton = primaryButton, let secondaryButton = secondaryButton { - primaryButton.removeFromSuperview() - secondaryButton.removeFromSuperview() - setupConstraintsForViewWithButtons() - } - } - - public func hideBothButtons() { - primaryButton?.isHidden = true - secondaryButton?.isHidden = true - } - - override open func horizontalAlignment() -> UIStackView.Alignment { + + // MARK: - MVMCoreUIViewConstrainingProtocol + open func horizontalAlignment() -> UIStackView.Alignment { return .center } -} - -// MARK: - Deprecate -extension TwoButtonView { - @available(*, deprecated) - open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { - setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap) - if primaryButtonMap != nil, secondaryButtonMap != nil { - primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) - secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) - } else if primaryButtonMap != nil { - primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) - primaryButton?.bordered = false - } else if secondaryButtonMap != nil { - secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) - secondaryButton?.bordered = true + + // MARK: - ModelMoleculeViewProtocol + public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + guard let model = model as? TwoButtonViewModel else { return } + if let primaryModel = model.primaryButton { + showPrimaryButton() + primaryButton.setWithModel(primaryModel, delegateObject, additionalData) + } else { + hidePrimaryButton() + } + if let secondaryModel = model.secondaryButton { + showSecondaryButton() + secondaryButton.setWithModel(secondaryModel, delegateObject, additionalData) + } else { + hideSecondaryButton() } } - - @available(*, deprecated) - open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { - let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton) - let primaryButtonMap = buttonMap?.optionalDictionaryForKey(KeyPrimaryButton) - setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) - } - - @available(*, deprecated) - public convenience init(buttonSmall small: Bool, buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: AnyHashable]?, buttonDelegate: Any?) { - self.init() - setup(withButtonMap: buttonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) - primaryButton?.setAsSmall(small) - secondaryButton?.setAsSmall(small) - } - - @available(*, deprecated) - public convenience init(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { - self.init() - setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) - } -} - -extension TwoButtonView: ModelMoleculeViewProtocol { - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - guard let model = model as? TwoButtonViewModel else { return } - setupUI(primaryButtonShowing: model.primaryButton != nil, secondaryButtonShowing: model.secondaryButton != nil) - setDefaultCustom() - primaryButton?.setWithModel(model.primaryButton, delegateObject, additionalData) - secondaryButton?.setWithModel(model.secondaryButton, delegateObject, additionalData) - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - } } From 37228669e08678469549523d5bf2647a4f7f3ff7 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 31 Jan 2020 16:27:20 -0500 Subject: [PATCH 02/57] Two button remove legacy --- MVMCoreUI/Atoms/Buttons/ButtonModel.swift | 6 ++++ .../TwoButtonView.swift | 17 ++++++++++- .../TwoButtonViewModel.swift | 28 ++++++++++++++++++- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift index 9eb284d7..cfe8bb2f 100644 --- a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift @@ -41,6 +41,12 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { self.action = action } + init(secondaryButtonWith title: String, action: ActionModelProtocol) { + self.title = title + self.action = action + style = .secondary + } + private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift index 9a4f31f9..a12bf03f 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -12,7 +12,8 @@ import UIKit open var primaryButton: PillButton = PillButton() open var secondaryButton: PillButton = PillButton() private var stack = UIStackView() - + private var equalWidthConstraint: NSLayoutConstraint? + public init() { super.init(frame: .zero) } @@ -47,31 +48,45 @@ import UIKit NSLayoutConstraint.constraintPinSubview(toSuperview: stack) stack.axis = .horizontal stack.spacing = 10 + equalWidthConstraint = secondaryButton.widthAnchor.constraint(equalTo: primaryButton.widthAnchor, multiplier: 1) + equalWidthConstraint?.isActive = true } // MARK: - Stack Manipulation public func showPrimaryButton() { if primaryButton.superview == nil { stack.addArrangedSubview(primaryButton) + primaryButton.isHidden = false + } + if secondaryButton.superview != nil { + equalWidthConstraint?.isActive = true } } public func showSecondaryButton() { if secondaryButton.superview == nil { stack.addArrangedSubview(secondaryButton) + secondaryButton.isHidden = false + } + if primaryButton.superview != nil { + equalWidthConstraint?.isActive = true } } public func hidePrimaryButton() { if primaryButton.superview != nil { stack.removeArrangedSubview(primaryButton) + primaryButton.isHidden = true } + equalWidthConstraint?.isActive = false } public func hideSecondaryButton() { if secondaryButton.superview != nil { stack.removeArrangedSubview(secondaryButton) + secondaryButton.isHidden = true } + equalWidthConstraint?.isActive = false } // MARK: - MVMCoreUIMoleculeViewProtocol diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift index a7abde9f..5938692b 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift @@ -8,9 +8,35 @@ import UIKit -public struct TwoButtonViewModel: MoleculeModelProtocol { +public class TwoButtonViewModel: MoleculeModelProtocol { public static var identifier: String = "twoButtonView" public var backgroundColor: Color? public var primaryButton: ButtonModel? public var secondaryButton: ButtonModel? + + private enum CodingKeys: String, CodingKey { + case moleculeName + case backgroundColor + case primaryButton + case secondaryButton + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + primaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .primaryButton) + secondaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .secondaryButton) + // Default value + if secondaryButton?.style == nil { + secondaryButton?.style = .secondary + } + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(primaryButton, forKey: .primaryButton) + try container.encodeIfPresent(secondaryButton, forKey: .secondaryButton) + } } From e2f1da7c276519ade5e87568f3da296c5a38dd36 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 31 Jan 2020 16:29:46 -0500 Subject: [PATCH 03/57] estimated height --- .../Molecules/HorizontalCombinationViews/TwoButtonView.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift index a12bf03f..31fd6f37 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -101,6 +101,11 @@ import UIKit } // MARK: - ModelMoleculeViewProtocol + public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + guard let model = molecule as? TwoButtonViewModel else { return 0 } + return PillButton.estimatedHeight(forRow: model.primaryButton ?? model.secondaryButton, delegateObject: delegateObject) + } + public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) guard let model = model as? TwoButtonViewModel else { return } From 205e9707e6a92ec9c04bf2094d59cc73fee795f3 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 31 Jan 2020 16:37:24 -0500 Subject: [PATCH 04/57] move legacy --- MVMCoreUI.xcodeproj/project.pbxproj | 4 ++-- .../Views}/PrimaryButtonView.h | 0 .../Views}/PrimaryButtonView.m | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename MVMCoreUI/{Molecules/HorizontalCombinationViews => Legacy/Views}/PrimaryButtonView.h (100%) rename MVMCoreUI/{Molecules/HorizontalCombinationViews => Legacy/Views}/PrimaryButtonView.m (100%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index a35514cb..1a84907a 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -827,6 +827,8 @@ D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */, D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */, D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */, + 94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */, + 94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */, D282AACA2243C61700C46919 /* ButtonView.swift */, ); path = Views; @@ -871,8 +873,6 @@ D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */, D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */, D28A837E23CCA96400DFE4FC /* TabsModel.swift */, - 94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */, - 94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */, ); path = HorizontalCombinationViews; sourceTree = ""; diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.h b/MVMCoreUI/Legacy/Views/PrimaryButtonView.h similarity index 100% rename from MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.h rename to MVMCoreUI/Legacy/Views/PrimaryButtonView.h diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m b/MVMCoreUI/Legacy/Views/PrimaryButtonView.m similarity index 100% rename from MVMCoreUI/Molecules/HorizontalCombinationViews/PrimaryButtonView.m rename to MVMCoreUI/Legacy/Views/PrimaryButtonView.m From 4bcfdb96db51ad11ac998c223dcb81ddee23d2a1 Mon Sep 17 00:00:00 2001 From: Kruthika KP <> Date: Wed, 5 Feb 2020 13:17:50 +0530 Subject: [PATCH 05/57] 18936 - Left Variable Icon - with - Right Caret - initial commit. --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ++ .../LeftVariableIconRightCaretList.swift | 115 ++++++++++++++++++ .../LeftVariableIconRightCaretListModel.swift | 39 ++++++ .../OtherHandlers/MoleculeObjectMapping.swift | 1 + 4 files changed, 163 insertions(+) create mode 100644 MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift create mode 100644 MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index a35514cb..7cc6f284 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -95,6 +95,8 @@ 0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; }; 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; }; 31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; }; + 8D24041123E7FB9E009E23BE /* LeftVariableIconRightCaretList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041023E7FB9E009E23BE /* LeftVariableIconRightCaretList.swift */; }; + 8D24041523E7FC0B009E23BE /* LeftVariableIconRightCaretListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041423E7FC0B009E23BE /* LeftVariableIconRightCaretListModel.swift */; }; 9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; }; 943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; }; 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; }; @@ -408,6 +410,8 @@ 0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = ""; }; 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = ""; }; 31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = ""; }; + 8D24041023E7FB9E009E23BE /* LeftVariableIconRightCaretList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftVariableIconRightCaretList.swift; sourceTree = ""; }; + 8D24041423E7FC0B009E23BE /* LeftVariableIconRightCaretListModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftVariableIconRightCaretListModel.swift; sourceTree = ""; }; 9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = ""; }; 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = ""; }; 943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = ""; }; @@ -881,6 +885,8 @@ isa = PBXGroup; children = ( D2E2A99723D8D63C000B42E6 /* ActionDetailWithImageModel.swift */, + 8D24041023E7FB9E009E23BE /* LeftVariableIconRightCaretList.swift */, + 8D24041423E7FC0B009E23BE /* LeftVariableIconRightCaretListModel.swift */, 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */, D28A839023CD4FD400DFE4FC /* CornerLabelsModel.swift */, 01509D902327ECE600EF99AA /* CornerLabels.swift */, @@ -1673,6 +1679,7 @@ C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, + 8D24041523E7FC0B009E23BE /* LeftVariableIconRightCaretListModel.swift in Sources */, D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */, 012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */, D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */, @@ -1685,6 +1692,7 @@ D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */, D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */, 0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */, + 8D24041123E7FB9E009E23BE /* LeftVariableIconRightCaretList.swift in Sources */, D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */, DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */, 0A21DB89235E06EF00C160A2 /* MFMdnTextField.m in Sources */, diff --git a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift new file mode 100644 index 00000000..ba540437 --- /dev/null +++ b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift @@ -0,0 +1,115 @@ +// +// LeftVariableIconRightCaretList.swift +// MVMCoreUI +// +// Created by Kruthika KP on 03/02/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +import UIKit + +@objcMembers public class LeftVariableIconRightCaretList : TableViewCell { + + //----------------------------------------------------- + // MARK: - Outlets + //------------------------------------------------------- + + let leftImage = MFLoadImageView() + let leftLabel = Label.commonLabelB2(true) + let rightLabel = Label.commonLabelB2(true) + + + //------------------------------------------------------ + // MARK: - Properties + //------------------------------------------------------- + let spaceBetweenLabels : CGFloat = 40 + let horizontalPadding : CGFloat = 10 + let rightLabelTrailing : CGFloat = 20 + let cellHeight : CGFloat = 60 + let imageSize : CGFloat = 30 + + + //------------------------------------------------------ + // MARK: - Initialization + //-------------------------------------------------------- + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + setupView() + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setupView() + } + + + //----------------------------------------------------- + // MARK: - View Lifecycle + //------------------------------------------------------- + + open override func updateView(_ size: CGFloat) { + super.updateView(size) + leftImage.updateView(size) + leftLabel.updateView(size) + rightLabel.updateView(size) + + } + + override open func setupView() { + super.setupView() + guard leftImage.superview == nil else { + return + } + + addSubview(leftImage) + addSubview(leftLabel) + addSubview(rightLabel) + + + contentView.heightAnchor.constraint(equalToConstant: cellHeight).isActive = true + + leftImage.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor, constant: horizontalPadding).isActive = true + leftImage.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true + leftImage.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor).isActive = true + leftImage.widthAnchor.constraint(equalToConstant: imageSize).isActive = true + leftImage.heightAnchor.constraint(equalToConstant: imageSize).isActive = true + + leftLabel.leadingAnchor.constraint(equalTo: leftImage.trailingAnchor, constant: horizontalPadding).isActive = true + leftLabel.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true + leftLabel.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor).isActive = true + + + rightLabel.leadingAnchor.constraint(greaterThanOrEqualTo: leftLabel.trailingAnchor, constant: spaceBetweenLabels).isActive = true + rightLabel.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true + rightLabel.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor).isActive = true + layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightLabel.trailingAnchor, constant: rightLabelTrailing).isActive = true + } + + //---------------------------------------------------- + // MARK: - Molecule + //------------------------------------------------------ + + override open func reset() { + super.reset() + + leftImage.reset() + leftLabel.reset() + rightLabel.reset() + } + + open func setAsMolecule() { + setupView() + } + + public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + + super.setWithModel(model, delegateObject, additionalData) + guard let model = model as? LeftVariableIconRightCaretListModel else { return} + + leftImage.setWithModel(model.image, delegateObject, additionalData) + leftLabel.setWithModel(model.leftLabel, delegateObject, additionalData) + rightLabel.setWithModel(model.rightLabel, delegateObject, additionalData) + } +} diff --git a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift new file mode 100644 index 00000000..e0ee0fcb --- /dev/null +++ b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift @@ -0,0 +1,39 @@ +// +// LeftVariableIconRightCaretListModel.swift +// MVMCoreUI +// +// Created by Kruthika KP on 03/02/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class LeftVariableIconRightCaretListModel: ListItemModelProtocol { + + public var horizontalAlignment: UIStackView.Alignment? + public var verticalAlignment: UIStackView.Alignment? + public var useHorizontalMargins: Bool? + public var useVerticalMargins: Bool? + public var topMarginPadding: CGFloat? + public var bottomMarginPadding: CGFloat? + + + public var line: LineModel? = LineModel(type: .standard) + public var hideArrow: Bool? = false + public var backgroundColor: Color? + + public static var identifier: String = "listLVImg" + public var image: ImageViewModel + public var leftLabel: LabelModel + public var rightLabel: LabelModel + + + + public init(image: ImageViewModel, leftLabel: LabelModel, rightLabel: LabelModel) { + self.image = image + self.leftLabel = leftLabel + self.rightLabel = rightLabel + } + +} + diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index d3523ccf..0bb12509 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -70,6 +70,7 @@ import Foundation MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyToggle.self, viewModelClass: HeadlineBodyToggleModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyLinkToggle.self, viewModelClass: HeadlineBodyLinkToggleModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ActionDetailWithImage.self, viewModelClass: ActionDetailWithImageModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: LeftVariableIconRightCaretList.self, viewModelClass: LeftVariableIconRightCaretListModel.self) // List items MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeTableViewCell.self, viewModelClass: ListItemModel.self) From 8ca15468f4e993134070f6ccc3d0feb7d461bef5 Mon Sep 17 00:00:00 2001 From: Kruthika KP <> Date: Thu, 6 Feb 2020 16:30:20 +0530 Subject: [PATCH 06/57] changes to image leading space --- .../LeftRightViews/LeftVariableIconRightCaretList.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift index ba540437..def62ef8 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift @@ -24,7 +24,7 @@ import UIKit // MARK: - Properties //------------------------------------------------------- let spaceBetweenLabels : CGFloat = 40 - let horizontalPadding : CGFloat = 10 + let horizontalPadding : CGFloat = 12 let rightLabelTrailing : CGFloat = 20 let cellHeight : CGFloat = 60 let imageSize : CGFloat = 30 @@ -70,7 +70,7 @@ import UIKit contentView.heightAnchor.constraint(equalToConstant: cellHeight).isActive = true - leftImage.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor, constant: horizontalPadding).isActive = true + leftImage.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor).isActive = true leftImage.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true leftImage.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor).isActive = true leftImage.widthAnchor.constraint(equalToConstant: imageSize).isActive = true From 5f2abffba04f1dfba8b38d26cb70a75d5861b994 Mon Sep 17 00:00:00 2001 From: Kruthika KP <> Date: Thu, 6 Feb 2020 18:43:53 +0530 Subject: [PATCH 07/57] Changed TableViewCell to Container in Molecule class and ListItemModelProtocol to MoleculeModelProtocol --- .../LeftVariableIconRightCaretList.swift | 58 ++++++------------- .../LeftVariableIconRightCaretListModel.swift | 27 ++++++++- 2 files changed, 44 insertions(+), 41 deletions(-) diff --git a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift index def62ef8..f7b08220 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift @@ -9,42 +9,25 @@ import Foundation import UIKit -@objcMembers public class LeftVariableIconRightCaretList : TableViewCell { +@objcMembers public class LeftVariableIconRightCaretList : Container { //----------------------------------------------------- // MARK: - Outlets //------------------------------------------------------- let leftImage = MFLoadImageView() - let leftLabel = Label.commonLabelB2(true) - let rightLabel = Label.commonLabelB2(true) + let leftLabel = Label(frame: .zero) + let rightLabel = Label(frame: .zero) //------------------------------------------------------ // MARK: - Properties //------------------------------------------------------- - let spaceBetweenLabels : CGFloat = 40 - let horizontalPadding : CGFloat = 12 - let rightLabelTrailing : CGFloat = 20 - let cellHeight : CGFloat = 60 + let spaceBetweenLabels : CGFloat = 180 + let horizontalPadding : CGFloat = 14 let imageSize : CGFloat = 30 - //------------------------------------------------------ - // MARK: - Initialization - //-------------------------------------------------------- - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - setupView() - } - - required public init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - setupView() - } - - //----------------------------------------------------- // MARK: - View Lifecycle //------------------------------------------------------- @@ -63,28 +46,29 @@ import UIKit return } - addSubview(leftImage) - addSubview(leftLabel) - addSubview(rightLabel) + let container = MVMCoreUICommonViewsUtility.commonView() + addAndContain(container) + container.addSubview(leftImage) + container.addSubview(leftLabel) + container.addSubview(rightLabel) - contentView.heightAnchor.constraint(equalToConstant: cellHeight).isActive = true + self.translatesAutoresizingMaskIntoConstraints = false - leftImage.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor).isActive = true - leftImage.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true - leftImage.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor).isActive = true + leftImage.leadingAnchor.constraint(equalTo: container.leadingAnchor).isActive = true + leftImage.topAnchor.constraint(equalTo: container.topAnchor).isActive = true + leftImage.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true leftImage.widthAnchor.constraint(equalToConstant: imageSize).isActive = true leftImage.heightAnchor.constraint(equalToConstant: imageSize).isActive = true leftLabel.leadingAnchor.constraint(equalTo: leftImage.trailingAnchor, constant: horizontalPadding).isActive = true - leftLabel.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true - leftLabel.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor).isActive = true + leftLabel.topAnchor.constraint(equalTo: container.topAnchor).isActive = true + leftLabel.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true - rightLabel.leadingAnchor.constraint(greaterThanOrEqualTo: leftLabel.trailingAnchor, constant: spaceBetweenLabels).isActive = true - rightLabel.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true - rightLabel.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor).isActive = true - layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightLabel.trailingAnchor, constant: rightLabelTrailing).isActive = true + rightLabel.leadingAnchor.constraint(equalTo: leftLabel.trailingAnchor,constant: spaceBetweenLabels).isActive = true + rightLabel.topAnchor.constraint(equalTo: container.topAnchor).isActive = true + rightLabel.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true } //---------------------------------------------------- @@ -99,10 +83,6 @@ import UIKit rightLabel.reset() } - open func setAsMolecule() { - setupView() - } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.setWithModel(model, delegateObject, additionalData) diff --git a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift index e0ee0fcb..152f8128 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift @@ -8,7 +8,7 @@ import Foundation -public class LeftVariableIconRightCaretListModel: ListItemModelProtocol { +public class LeftVariableIconRightCaretListModel: MoleculeModelProtocol { public var horizontalAlignment: UIStackView.Alignment? public var verticalAlignment: UIStackView.Alignment? @@ -19,7 +19,7 @@ public class LeftVariableIconRightCaretListModel: ListItemModelProtocol { public var line: LineModel? = LineModel(type: .standard) - public var hideArrow: Bool? = false + public var hideArrow: Bool? public var backgroundColor: Color? public static var identifier: String = "listLVImg" @@ -35,5 +35,28 @@ public class LeftVariableIconRightCaretListModel: ListItemModelProtocol { self.rightLabel = rightLabel } + private enum CodingKeys: String, CodingKey { + case moleculeName + case leftLabel + case rightLabel + case image + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel) + rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) + image = try typeContainer.decode(ImageViewModel.self, forKey: .image) + } + + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(LeftVariableIconRightCaretListModel.identifier, forKey: .moleculeName) + try container.encode(leftLabel, forKey: .leftLabel) + try container.encode(rightLabel, forKey: .rightLabel) + try container.encodeIfPresent(image, forKey: .image) + } + } From 15bfb6b4814360b439183c724c047ae086fe23cc Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 6 Feb 2020 09:31:23 -0500 Subject: [PATCH 08/57] Bug fix and general shape-up --- .../TextFields/ItemDropdownEntryField.swift | 7 +- .../ItemDropdownEntryFieldModel.swift | 4 + .../Atoms/TextFields/TextEntryField.swift | 5 +- MVMCoreUI/Atoms/Views/Label/Label.swift | 25 +++- MVMCoreUI/Atoms/Views/Label/LabelModel.swift | 26 ++-- .../ThreeLayerTableViewController.swift | 10 +- .../ListItemModelProtocol.swift | 15 +- .../Items/DropDownFilterTableViewCell.swift | 3 +- .../Items/MoleculeTableViewCell.swift | 23 +-- .../HeadlineBody.swift | 41 +++--- .../HeadlineBodyModel.swift | 1 - .../Templates/MoleculeListTemplate.swift | 131 ++++++++++++------ 12 files changed, 189 insertions(+), 102 deletions(-) diff --git a/MVMCoreUI/Atoms/TextFields/ItemDropdownEntryField.swift b/MVMCoreUI/Atoms/TextFields/ItemDropdownEntryField.swift index d1728b46..48728ce9 100644 --- a/MVMCoreUI/Atoms/TextFields/ItemDropdownEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/ItemDropdownEntryField.swift @@ -26,6 +26,10 @@ open class ItemDropdownEntryField: BaseDropdownEntryField { /// Closure passed here will run upon dismissing the selection picker. public var observeDropdownSelection: ((String)->())? + public var itemDropdownEntryFieldModel: ItemDropdownEntryFieldModel? { + return model as? ItemDropdownEntryFieldModel + } + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -100,7 +104,7 @@ open class ItemDropdownEntryField: BaseDropdownEntryField { setPickerDelegates(delegate: self) if let pickerView = pickerView { - self.pickerView(pickerView, didSelectRow: 0, inComponent: 0) + self.pickerView(pickerView, didSelectRow: model.selectedIndex, inComponent: 0) } } } @@ -127,6 +131,7 @@ extension ItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource { observeDropdownChange?(text ?? "", pickerData[row]) text = pickerData[row] + itemDropdownEntryFieldModel?.selectedIndex = row } } diff --git a/MVMCoreUI/Atoms/TextFields/ItemDropdownEntryFieldModel.swift b/MVMCoreUI/Atoms/TextFields/ItemDropdownEntryFieldModel.swift index 03c1cf40..56612b7b 100644 --- a/MVMCoreUI/Atoms/TextFields/ItemDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atoms/TextFields/ItemDropdownEntryFieldModel.swift @@ -16,6 +16,7 @@ } public var options: [String] = [] + public var selectedIndex: Int = 0 //-------------------------------------------------- // MARK: - Keys @@ -24,6 +25,7 @@ private enum CodingKeys: String, CodingKey { case moleculeName case options + case selectedIndex } //-------------------------------------------------- @@ -34,6 +36,7 @@ try super.init(from: decoder) let typeContainer = try decoder.container(keyedBy: CodingKeys.self) options = try typeContainer.decode([String].self, forKey: .options) + selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) ?? 0 } public override func encode(to encoder: Encoder) throws { @@ -41,5 +44,6 @@ var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(options, forKey: .options) + try container.encode(options, forKey: .selectedIndex) } } diff --git a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift index 66f3ecd4..57fdbb73 100644 --- a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift @@ -85,7 +85,10 @@ import UIKit /// The text of this TextField. open override var text: String? { get { return textField.text } - set { textField.text = newValue } + set { + textField.text = newValue + (model as? TextEntryFieldModel)?.text = newValue + } } /// Placeholder access for the TextField. diff --git a/MVMCoreUI/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atoms/Views/Label/Label.swift index 208676df..576f66b9 100644 --- a/MVMCoreUI/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label/Label.swift @@ -220,17 +220,27 @@ public typealias ActionBlock = () -> () } public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + clauses = [] - guard let labelModel = model as? LabelModel else { return } + + guard let labelModel = model as? LabelModel else { + text = "" + return + } + attributedText = nil + originalAttributedString = 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 } @@ -239,9 +249,11 @@ public typealias ActionBlock = () -> () if let backgroundColor = labelModel.backgroundColor { self.backgroundColor = backgroundColor.uiColor } + if let accessibilityText = labelModel.accessibilityText { accessibilityLabel = accessibilityText } + if let fontStyle = labelModel.fontStyle { MFStyler.styleLabel(self, withStyle: fontStyle) MFStyler.styleLabel(self, withStyle: fontStyle, genericScaling: false) @@ -264,19 +276,23 @@ public typealias ActionBlock = () -> () if let attributes = labelModel.attributes, let labelText = text { let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: font.withSize(standardFontSize), NSAttributedString.Key.foregroundColor: textColor as UIColor]) + for attribute in attributes { let range = NSRange(location: attribute.location, length: attribute.length) switch attribute { case _ as LabelAttributeUnderlineModel: attributedString.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range) + case _ 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 { @@ -293,6 +309,7 @@ public typealias ActionBlock = () -> () 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) @@ -320,6 +337,7 @@ public typealias ActionBlock = () -> () } } addActionAttributes(range: range, string: attributedString) + default: continue } @@ -381,8 +399,9 @@ public typealias ActionBlock = () -> () } if let attributes = json?.optionalArrayForKey("attributes"), let labelText = label.text { - let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: mvmLabel?.font.withSize(mvmLabel!.standardFontSize) ?? label.font as UIFont, - NSAttributedString.Key.foregroundColor: label.textColor as UIColor]) + let attributedString = NSMutableAttributedString(string: labelText, + attributes: [NSAttributedString.Key.font: mvmLabel?.font.withSize(mvmLabel!.standardFontSize) ?? label.font as UIFont, + NSAttributedString.Key.foregroundColor: label.textColor as UIColor]) for case let attribute as [String: Any] in attributes { guard let attributeType = attribute.optionalStringForKey(KeyType), let location = attribute["location"] as? Int, diff --git a/MVMCoreUI/Atoms/Views/Label/LabelModel.swift b/MVMCoreUI/Atoms/Views/Label/LabelModel.swift index b0ad442f..731b23da 100644 --- a/MVMCoreUI/Atoms/Views/Label/LabelModel.swift +++ b/MVMCoreUI/Atoms/Views/Label/LabelModel.swift @@ -48,19 +48,19 @@ import Foundation 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(Color.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.decodeModelsIfPresent(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) + moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName) + text = try typeContainer.decode(String.self, forKey: .text) + accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) + textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + fontStyle = try typeContainer.decodeIfPresent(String.self, forKey: .fontStyle) + fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName) + fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize) + textAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .textAlignment) + attributes = try typeContainer.decodeModelsIfPresent(codingKey: .attributes, typeCodingKey: AttributeTypeKey.type) as? [LabelAttributeModel] + html = try typeContainer.decodeIfPresent(String.self, forKey: .html) + hero = try typeContainer.decodeIfPresent(Int.self, forKey: .hero) + makeWholeViewClickable = try typeContainer.decodeIfPresent(Bool.self, forKey: .makeWholeViewClickable) } public func encode(to encoder: Encoder) throws { diff --git a/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift b/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift index 5045d5a4..3176df92 100644 --- a/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift +++ b/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift @@ -68,9 +68,8 @@ open class ThreeLayerTableViewController: MFProgrammaticTableViewController { open override func updateViewConstraints() { super.updateViewConstraints() - guard let tableView = tableView else { - return - } + + guard let tableView = tableView else { return } let minimumSpace: CGFloat = minimumFillSpace() var currentSpace: CGFloat = 0 @@ -90,9 +89,8 @@ open class ThreeLayerTableViewController: MFProgrammaticTableViewController { totalMinimumSpace += minimumSpace } - guard fillTop || fillBottom else { - return - } + guard fillTop || fillBottom else { return } + let newSpace = MVMCoreUIUtility.getVariableConstraintHeight(currentSpace, in: tableView, minimumHeight: totalMinimumSpace) // If the bottom view is outside of the scroll, then only the top view constraint is being used, so we have to double it to account for the bottom constraint not being there when we compare to the new value. diff --git a/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift index 9d424a2b..c6be0488 100644 --- a/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift @@ -17,19 +17,14 @@ public protocol ListItemModelProtocol: ContainerModelProtocol, MoleculeModelProt // Not a strict requirement. extension ListItemModelProtocol { + public var action: ActionModelProtocol? { - get { - return nil - } - set { - } + get { return nil } + set { } } public var style: String? { - get { - return nil - } - set { - } + get { return nil } + set { } } } diff --git a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift index 8c813d24..877af234 100644 --- a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift @@ -26,6 +26,7 @@ import UIKit super.setupView() guard dropDown.superview == nil else { return } + addMolecule(dropDown) dropDown.observeDropdownChange = { [weak self] oldValue, newValue in @@ -40,7 +41,7 @@ import UIKit self.delegateObject?.moleculeDelegate?.removeMolecules(json2d[self.previousIndex], sender: self, animation: .fade) } - self.delegateObject?.moleculeDelegate?.addMolecules(json2d[index], sender: self, animation: .fade) + self.delegateObject?.moleculeDelegate?.addMolecules(json2d[index], sender: self, animation: .none) self.previousIndex = index } } diff --git a/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift b/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift index 56ff1ca9..9f27a918 100644 --- a/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift @@ -8,14 +8,19 @@ import UIKit + @objcMembers open class MoleculeTableViewCell: TableViewCell { // MARK: - MVMCoreUIMoleculeViewProtocol + public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.setWithModel(model, delegateObject, additionalData) + guard let model = model as? ListItemModel else { return } + if molecule != nil { (molecule as? ModelMoleculeViewProtocol)?.setWithModel(model.molecule, delegateObject, additionalData) + } else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(model.molecule, delegateObject, false) { addMolecule(moleculeView) } @@ -24,28 +29,28 @@ import UIKit } public override class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { - guard let moleculeModel = (model as? ListItemModel)?.molecule else { - return "\(self)<>" - } + guard let moleculeModel = (model as? ListItemModel)?.molecule else { return "\(self)<>" } + let className = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type let moleculeName = className?.nameForReuse(moleculeModel, delegateObject) ?? moleculeModel.moleculeName ?? "" + return "\(self)<\(moleculeName)>" } public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule), - let theClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON) else { - return nil - } + let theClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON) + else { return nil } + return theClass.requiredModules?(moleculeJSON, delegateObject: delegateObject, error: error) } public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { guard let moleculeModel = (molecule as? MoleculeContainerModel)?.molecule, let classType = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type, - let height = classType.estimatedHeight(forRow: moleculeModel, delegateObject: delegateObject) else { - return 80 - } + let height = classType.estimatedHeight(forRow: moleculeModel, delegateObject: delegateObject) + else { return 80 } + return max(2 * PaddingDefaultVerticalSpacing3, height) } } diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBody.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBody.swift index 3a270ad5..8226dfc1 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBody.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBody.swift @@ -24,9 +24,8 @@ open class HeadlineBody: View { // MARK: - Styling func style(with styleString: String?) { - guard let styleString = styleString else { - return - } + guard let styleString = styleString else { return } + switch styleString { case "header": stylePageHeader() @@ -72,10 +71,9 @@ open class HeadlineBody: View { open override func setupView() { super.setupView() - guard subviews.count == 0 else { - return - } - translatesAutoresizingMaskIntoConstraints = false + + guard subviews.isEmpty else { return } + backgroundColor = .clear clipsToBounds = true @@ -86,9 +84,9 @@ open class HeadlineBody: View { view.addSubview(headlineLabel) view.addSubview(messageLabel) - headlineLabel.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical) - messageLabel.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical) - view.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical) + headlineLabel.setContentHuggingPriority(.required, for: .vertical) + messageLabel.setContentHuggingPriority(.required, for: .vertical) + view.setContentHuggingPriority(.required, for: .vertical) headlineLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true @@ -110,7 +108,10 @@ open class HeadlineBody: View { view.bottomAnchor.constraint(equalTo: messageLabel.bottomAnchor, constant: 0).isActive = true } + //-------------------------------------------------- // MARK: - Constraining + //-------------------------------------------------- + public func setSpacing() { if headlineLabel.hasText && messageLabel.hasText { spaceBetweenLabels?.constant = spaceBetweenLabelsConstant @@ -119,25 +120,32 @@ open class HeadlineBody: View { } } - // MARK:- ModelMoleculeViewProtocol + //-------------------------------------------------- + // MARK: - ModelMoleculeViewProtocol + //-------------------------------------------------- + public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 58 } public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) - guard let headlineBodyModel = model as? HeadlineBodyModel else { - return - } + + guard let headlineBodyModel = model as? HeadlineBodyModel else { return } style(with: headlineBodyModel.style) - + + print("Headline -H: \(headlineBodyModel.headline?.text ?? "~nada~")") + print("Headline -B: \(headlineBodyModel.body?.text ?? "~nada~")") + headlineLabel.setWithModel(headlineBodyModel.headline, delegateObject, additionalData) messageLabel.setWithModel(headlineBodyModel.body, delegateObject, additionalData) } + //-------------------------------------------------- // MARK: - MVMCoreUIMoleculeViewProtocol + //-------------------------------------------------- + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) @@ -159,4 +167,3 @@ open class HeadlineBody: View { return 58 } } - diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift index 62199654..1fbe98e7 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift @@ -20,4 +20,3 @@ import Foundation self.headline = headline } } - diff --git a/MVMCoreUI/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Templates/MoleculeListTemplate.swift index 75ef7d2f..f9319927 100644 --- a/MVMCoreUI/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeListTemplate.swift @@ -9,52 +9,67 @@ import UIKit open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol { + //-------------------------------------------------- + // MARK: - Stored Properties + //-------------------------------------------------- public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)]? + var observer: NSKeyValueObservation? public var templateModel: ListPageTemplateModel? + + //-------------------------------------------------- + // MARK: - Computed Properties + //-------------------------------------------------- + @objc public override func parsePageJSON() throws { try parseTemplateJSON() } open override var loadObject: MVMCoreLoadObject? { didSet { - if loadObject != oldValue { - updateRequiredModules() - observer?.invalidate() - if let newObject = loadObject { - observer = newObject.observe(\MVMCoreLoadObject.pageJSON, options: [.old, .new]) { [weak self] (object, change) in - self?.updateRequiredModules() - } + guard loadObject != oldValue else { return } + + updateRequiredModules() + observer?.invalidate() + if let newObject = loadObject { + observer = newObject.observe(\MVMCoreLoadObject.pageJSON, options: [.old, .new]) { [weak self] object, change in + self?.updateRequiredModules() } } } } + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + open override func viewForTop() -> UIView { guard let headerModel = templateModel?.header, - let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(headerModel, delegateObject() as? MVMCoreUIDelegateObject, false) else { - return super.viewForTop() - } + let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(headerModel, delegateObject() as? MVMCoreUIDelegateObject, false) + else { return super.viewForTop() } // Temporary, Default the horizontal padding if var container = templateModel?.header as? ContainerModelProtocol, container.useHorizontalMargins == nil { container.useHorizontalMargins = true } + return molecule } override open func viewForBottom() -> UIView { guard let footerModel = templateModel?.footer, - let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(footerModel, delegateObject() as? MVMCoreUIDelegateObject, false) else { - return super.viewForBottom() - } + let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(footerModel, delegateObject() as? MVMCoreUIDelegateObject, false) + else { return super.viewForBottom() } + return molecule } open override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer) -> Bool { + guard super.shouldFinishProcessingLoad(loadObject, error: error) else { return false } + // This template requires atleast one of the three layers. if templateModel?.header == nil, templateModel?.molecules?.count ?? 0 == 0, @@ -72,7 +87,10 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol registerWithTable() } - // MARK: - table + //-------------------------------------------------- + // MARK: - Table View + //-------------------------------------------------- + open override func registerWithTable() { super.registerWithTable() guard let moleculesInfo = moleculesInfo else { return } @@ -84,9 +102,9 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { guard let moleculeInfo = moleculesInfo?[indexPath.row], - let estimatedHeight = (moleculeInfo.class as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(forRow: moleculeInfo.molecule, delegateObject: delegateObject() as? MVMCoreUIDelegateObject) else { - return 0 - } + let estimatedHeight = (moleculeInfo.class as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(forRow: moleculeInfo.molecule, delegateObject: delegateObject() as? MVMCoreUIDelegateObject) + else { return 0 } + return estimatedHeight } @@ -95,18 +113,22 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let moleculeInfo = moleculesInfo?[indexPath.row], - let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier) else { - return UITableViewCell() - } + let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier) + else { return UITableViewCell() } + let delegate = delegateObject() as? MVMCoreUIDelegateObject let moleculeCell = cell as? MVMCoreUIMoleculeViewProtocol moleculeCell?.reset?() + if let protocolCell = cell as? MoleculeListCellProtocol { protocolCell.setLines(with: templateModel?.line, delegateObject: delegate, additionalData: nil, indexPath: indexPath) } + (moleculeCell as? ModelMoleculeViewProtocol)?.setWithModel(moleculeInfo.molecule, delegate, nil) - moleculeCell?.updateView(tableView.bounds.width) + moleculeCell?.updateView(tableView.bounds.width) + return cell } @@ -118,16 +140,18 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if let cell = tableView.cellForRow(at: indexPath) as? MoleculeListCellProtocol { cell.didSelectCell(at: indexPath, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil) } } - // MARK: - cache handling + //-------------------------------------------------- + // MARK: - Cache Handling + //-------------------------------------------------- + open override func pageTypesToListenFor() -> [Any]? { - guard let pageType = self.pageType else { - return super.pageTypesToListenFor() - } + guard let pageType = self.pageType else { return super.pageTypesToListenFor() } return [pageType] } @@ -135,8 +159,12 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol return loadObject?.requestParameters?.modules } + //-------------------------------------------------- // MARK: - MoleculeDelegateProtocol + //-------------------------------------------------- + open override func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) { + if let tableView = tableView { let point = molecule.convert(molecule.bounds.origin, to: tableView) if let indexPath = tableView.indexPathForRow(at: point), tableView.indexPathsForVisibleRows?.contains(indexPath) ?? false { @@ -159,6 +187,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol DispatchQueue.main.async { guard let indexPath = self.tableView?.indexPath(for: sender) else { return } var indexPaths: [IndexPath] = [] + for molecule in tmpMolecules { if let info = self.getMoleculeInfo(with: molecule) { self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier) @@ -167,6 +196,9 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol indexPaths.append(IndexPath(row: index, section: 0)) } } + + print("ADD PATHS: \(indexPaths)") + self.tableView?.insertRows(at: indexPaths, with: animation) self.updateViewConstraints() self.view.layoutIfNeeded() @@ -184,25 +216,31 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } var indexPaths: [IndexPath] = [] + //TODO: cehck for molecule protocola eqality + for molecule in tmpMolecules { - if let removeIndex = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in - return molecule.toJSONString() == moleculeInfo.molecule.toJSONString() - }) { + if let removeIndex = moleculesInfo?.firstIndex(where: { molecule.toJSON() == $0.molecule.toJSON() }) { + moleculesInfo?.remove(at: removeIndex) indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0)) } } - self.tableView?.deleteRows(at: indexPaths, with: animation) - self.updateViewConstraints() - self.view.layoutIfNeeded() + + print("REMOVE PATHS: \(indexPaths)") + + tableView?.deleteRows(at: indexPaths, with: animation) + updateViewConstraints() + view.layoutIfNeeded() } public func addMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) { + // This dispatch is needed to fix a race condition that can occur if this function is called during the table setup. DispatchQueue.main.async { guard let indexPath = self.tableView?.indexPath(for: sender) else { return } var indexPaths: [IndexPath] = [] + for molecule in molecules { if let info = self.getMoleculeInfo(with: molecule) { self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier) @@ -211,6 +249,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol indexPaths.append(IndexPath(row: index, section: 0)) } } + self.tableView?.insertRows(at: indexPaths, with: animation) self.updateViewConstraints() self.view.layoutIfNeeded() @@ -218,35 +257,42 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } public func removeMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) { + var indexPaths: [IndexPath] = [] //TODO: cehck for molecule protocola eqality + for molecule in molecules { - if let removeIndex = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in - return molecule.toJSONString() == moleculeInfo.molecule.toJSONString() - }) { + if let removeIndex = moleculesInfo?.firstIndex(where: { molecule.toJSON() == $0.molecule.toJSON() }) { moleculesInfo?.remove(at: removeIndex) indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0)) } } - self.tableView?.deleteRows(at: indexPaths, with: animation) - self.updateViewConstraints() - self.view.layoutIfNeeded() + + tableView?.deleteRows(at: indexPaths, with: animation) + updateViewConstraints() + view.layoutIfNeeded() } + //-------------------------------------------------- // MARK: - Convenience + //-------------------------------------------------- + /// Returns the (identifier, class) of the molecule for the given map. func getMoleculeInfo(with listItem: ListItemModelProtocol?) -> (identifier: String, class: AnyClass, molecule: ListItemModelProtocol)? { + guard let listItem = listItem, let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(listItem), - let moleculeName = (moleculeClass as? ModelMoleculeViewProtocol.Type)?.nameForReuse(listItem, delegateObject() as? MVMCoreUIDelegateObject) ?? listItem.moleculeName else { - return nil - } + let moleculeName = (moleculeClass as? ModelMoleculeViewProtocol.Type)?.nameForReuse(listItem, delegateObject() as? MVMCoreUIDelegateObject) ?? listItem.moleculeName + else { return nil } + return (moleculeName, moleculeClass, listItem) } /// Sets up the molecule list and ensures no errors loading all content. func getMoleculeInfoList() -> [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)]? { + var moleculeList: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)] = [] + if let molecules = templateModel?.molecules { for molecule in molecules { if let info = getMoleculeInfo(with: molecule) { @@ -254,6 +300,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } } } + return moleculeList.count > 0 ? moleculeList : nil } @@ -271,15 +318,19 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol /// Gets modules required by the loadObject.pageJSON. open func requiredModules() -> [Any]? { + let modules: NSMutableArray = [] let delegate = delegateObject() as? MVMCoreUIDelegateObject + MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate, moduleList: modules, errorList: nil) MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate, moduleList: modules, errorList: nil) + if let molecules = loadObject?.pageJSON?.optionalArrayForKey(KeyMolecules) as? [[AnyHashable: Any]] { for molecule in molecules { MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: molecule, delegateObject: delegate, moduleList: modules, errorList: nil) } } + return modules as? [Any] } } From 595dc99936ad24e1579b3c9d784d49756f21abfc Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 6 Feb 2020 09:50:03 -0500 Subject: [PATCH 09/57] button minimum caretLink --- MVMCoreUI/Atoms/Buttons/CaretButton.swift | 38 +++++------------------ MVMCoreUI/Atoms/Buttons/PillButton.swift | 6 ++-- 2 files changed, 10 insertions(+), 34 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/CaretButton.swift b/MVMCoreUI/Atoms/Buttons/CaretButton.swift index 3fcf453a..97f8d55e 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretButton.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretButton.swift @@ -8,7 +8,7 @@ // -open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol, ModelMoleculeViewProtocol { +open class CaretButton: Button, MVMCoreUIViewConstrainingProtocol { //------------------------------------------------------ // MARK: - Constants @@ -49,7 +49,9 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI didSet { changeCaretColor() } } - public func updateView(_ size: CGFloat) { } + public override func updateView(_ size: CGFloat) { + titleLabel?.font = MFStyler.fontB1() + } //------------------------------------------------------ // MARK: - Methods @@ -115,33 +117,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI setTitleColor(disabledColor, for: .disabled) } - @objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - setWithActionMap(json, delegateObject: delegateObject, additionalData: additionalData) - - guard let dictionary = json else { return } - - if let title = dictionary.optionalStringForKey(KeyTitle) { - setTitle(title, for: .normal) - } - - if let disableButtonAsAny = dictionary[KeyDisableButton], let isDisabled = disableButtonAsAny as? Bool { - isEnabled = !isDisabled - } - - if let backgroundColorHex = dictionary[KeyBackgroundColor] as? String { - backgroundColor = UIColor.mfGet(forHex: backgroundColorHex) - } - - if let enabledColorHex = dictionary["enabledColor"] as? String { - enabledColor = UIColor.mfGet(forHex: enabledColorHex) - } - - if let disabledColorHex = dictionary["disabledColor"] as? String { - disabledColor = UIColor.mfGet(forHex: disabledColorHex) - } - } - - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let caretLinkModel = model as? CaretLinkModel else { return } if let color = caretLinkModel.backgroundColor { backgroundColor = color.uiColor @@ -163,7 +139,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI return .leading } - public class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { - return 10 + open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return CARET_VIEW_HEIGHT } } diff --git a/MVMCoreUI/Atoms/Buttons/PillButton.swift b/MVMCoreUI/Atoms/Buttons/PillButton.swift index 0d0a3090..d3d09cee 100644 --- a/MVMCoreUI/Atoms/Buttons/PillButton.swift +++ b/MVMCoreUI/Atoms/Buttons/PillButton.swift @@ -97,9 +97,9 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation public static func getHeight(for buttonSize: ButtonSize?, size: CGFloat) -> CGFloat { switch buttonSize { case .tiny: - return MFSizeObject(standardSize: ButtonHeight.tiny.rawValue, standardiPadPortraitSize: 34, iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? 20 + return MFSizeObject(standardSize: ButtonHeight.tiny.rawValue, standardiPadPortraitSize: 34, iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? ButtonHeight.tiny.rawValue default: - return MFSizeObject(standardSize: ButtonHeight.standard.rawValue, standardiPadPortraitSize: 46, iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? 42 + return MFSizeObject(standardSize: ButtonHeight.standard.rawValue, standardiPadPortraitSize: 46, iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? ButtonHeight.standard.rawValue } } @@ -108,7 +108,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation case .tiny: return MFSizeObject(standardSize: 49.0, standardiPadPortraitSize: 90.0, iPadProLandscapeSize: 135.0)?.getValueBased(onSize: size) ?? 49.0 default: - return MFSizeObject(standardSize: 102.0, standardiPadPortraitSize: 136.0, iPadProLandscapeSize: 153.0)?.getValueBased(onSize: size) ?? 102.0 + return 151.0 } } From 0d4008dec7210b32582b2360ebc36e6ea273f730 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 6 Feb 2020 09:55:18 -0500 Subject: [PATCH 10/57] CaretLink --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ++++---- .../Atoms/Buttons/{CaretButton.swift => CaretLink.swift} | 6 +++--- .../HeadLineBodyCaretLinkImage.swift | 9 +-------- MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift | 2 +- 4 files changed, 9 insertions(+), 16 deletions(-) rename MVMCoreUI/Atoms/Buttons/{CaretButton.swift => CaretLink.swift} (97%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 752a5445..f97e81aa 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -327,7 +327,7 @@ DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */; }; DBC4391822442197001AB423 /* CaretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391622442196001AB423 /* CaretView.swift */; }; DBC4391922442197001AB423 /* DashLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391722442197001AB423 /* DashLine.swift */; }; - DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretButton.swift */; }; + DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretLink.swift */; }; DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */; }; DBEFFA04225A829700230692 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB891E822253FA8500022516 /* Label.swift */; }; /* End PBXBuildFile section */ @@ -658,7 +658,7 @@ DB891E822253FA8500022516 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = ""; }; DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = ""; }; DBC4391722442197001AB423 /* DashLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashLine.swift; sourceTree = ""; }; - DBC4391A224421A0001AB423 /* CaretButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretButton.swift; sourceTree = ""; }; + DBC4391A224421A0001AB423 /* CaretLink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretLink.swift; sourceTree = ""; }; DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelWithInternalButton.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -1168,7 +1168,7 @@ isa = PBXGroup; children = ( 01F2A03123A4498200D954D8 /* CaretLinkModel.swift */, - DBC4391A224421A0001AB423 /* CaretButton.swift */, + DBC4391A224421A0001AB423 /* CaretLink.swift */, D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */, D2E2A99E23E07F8A000B42E6 /* PillButton.swift */, D28A838823CCCFCB00DFE4FC /* LinkModel.swift */, @@ -1750,7 +1750,7 @@ 012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */, D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */, C003506123AA94CD00B6AC29 /* Button.swift in Sources */, - DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */, + DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */, 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */, 0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */, 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Buttons/CaretButton.swift b/MVMCoreUI/Atoms/Buttons/CaretLink.swift similarity index 97% rename from MVMCoreUI/Atoms/Buttons/CaretButton.swift rename to MVMCoreUI/Atoms/Buttons/CaretLink.swift index 405e110f..ca665928 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretButton.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretLink.swift @@ -1,5 +1,5 @@ // -// CaretButton.swift +// CaretLink.swift // MVMCoreUI // // Created by Kolli, Praneeth on 1/5/18. @@ -8,7 +8,7 @@ // -open class CaretButton: Button, MVMCoreUIViewConstrainingProtocol { +open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { //------------------------------------------------------ // MARK: - Constants @@ -148,6 +148,6 @@ open class CaretButton: Button, MVMCoreUIViewConstrainingProtocol { } open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - return CARET_VIEW_HEIGHT + return 10.5 } } diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index d5abe33f..2b3567d7 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -9,7 +9,7 @@ import Foundation @objcMembers public class HeadLineBodyCaretLinkImage: Container { let headlineBody = HeadlineBody(frame: .zero) - let caretButton = CaretButton(frame: .zero) + let caretButton = CaretLink(frame: .zero) let backgroundImageView = MFLoadImageView(pinnedEdges: .all) let maxWidth: CGFloat = 350.0 static let heightConstant: CGFloat = 320.0 @@ -66,13 +66,6 @@ import Foundation } // MARK: - MVMCoreUIMoleculeViewProtocol - open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - backgroundImageView.setWithJSON(json?.optionalDictionaryForKey("image"), delegateObject: delegateObject, additionalData: additionalData) - headlineBody.setWithJSON(json?.optionalDictionaryForKey("headlineBody"), delegateObject: delegateObject, additionalData: additionalData) - caretButton.setWithJSON(json?.optionalDictionaryForKey("caretLink"), delegateObject: delegateObject, additionalData: additionalData) - } - open override func reset() { super.reset() headlineBody.reset() diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index d3523ccf..8c1a36e3 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -30,7 +30,7 @@ import Foundation MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TwoButtonView.self, viewModelClass: TwoButtonViewModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Link.self, viewModelClass: LinkModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretButton.self, viewModelClass: CaretLinkModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretLink.self, viewModelClass: CaretLinkModel.self) // Entry Field MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TextEntryField.self, viewModelClass: TextEntryFieldModel.self) From b2241e47e1858888a249012efa0020c4fdacb77b Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 6 Feb 2020 10:29:52 -0500 Subject: [PATCH 11/57] fixing change --- MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift index 877af234..081da875 100644 --- a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift @@ -41,7 +41,7 @@ import UIKit self.delegateObject?.moleculeDelegate?.removeMolecules(json2d[self.previousIndex], sender: self, animation: .fade) } - self.delegateObject?.moleculeDelegate?.addMolecules(json2d[index], sender: self, animation: .none) + self.delegateObject?.moleculeDelegate?.addMolecules(json2d[index], sender: self, animation: .fade) self.previousIndex = index } } From a31d5ccfd8cf0b0b42490bebc07e5b5231ff9f7c Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 6 Feb 2020 11:07:09 -0500 Subject: [PATCH 12/57] redundant statement removed. --- MVMCoreUI/Atoms/TextFields/TextEntryField.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift index 57fdbb73..f7090edf 100644 --- a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift @@ -9,7 +9,7 @@ import UIKit -@objc public protocol ObservingTextFieldDelegate: NSObjectProtocol { +@objc public protocol ObservingTextFieldDelegate { /// Called when the entered text becomes valid based on the validation block @objc optional func isValid(textfield: TextEntryField?) /// Called when the entered text becomes invalid based on the validation block From f24485c699ff6cc3c264ce6532a3eb78ab5b9d08 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 6 Feb 2020 11:59:45 -0500 Subject: [PATCH 13/57] fix button order --- .../TwoButtonView.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift index 31fd6f37..56004de8 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -43,8 +43,8 @@ import UIKit stack.translatesAutoresizingMaskIntoConstraints = false addSubview(stack) - stack.addArrangedSubview(primaryButton) stack.addArrangedSubview(secondaryButton) + stack.addArrangedSubview(primaryButton) NSLayoutConstraint.constraintPinSubview(toSuperview: stack) stack.axis = .horizontal stack.spacing = 10 @@ -107,19 +107,19 @@ import UIKit } public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + super.setWithModel(model, delegateObject, additionalData) guard let model = model as? TwoButtonViewModel else { return } - if let primaryModel = model.primaryButton { - showPrimaryButton() - primaryButton.setWithModel(primaryModel, delegateObject, additionalData) - } else { - hidePrimaryButton() - } if let secondaryModel = model.secondaryButton { showSecondaryButton() secondaryButton.setWithModel(secondaryModel, delegateObject, additionalData) } else { hideSecondaryButton() } + if let primaryModel = model.primaryButton { + showPrimaryButton() + primaryButton.setWithModel(primaryModel, delegateObject, additionalData) + } else { + hidePrimaryButton() + } } } From 00b179d8c27f2d9f21e2545f1a8be698de68c5b0 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 6 Feb 2020 12:09:35 -0500 Subject: [PATCH 14/57] fix to reuse issue two button view --- .../HorizontalCombinationViews/TwoButtonView.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift index 56004de8..be6228f8 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -54,7 +54,7 @@ import UIKit // MARK: - Stack Manipulation public func showPrimaryButton() { - if primaryButton.superview == nil { + if !stack.arrangedSubviews.contains(primaryButton) { stack.addArrangedSubview(primaryButton) primaryButton.isHidden = false } @@ -64,8 +64,8 @@ import UIKit } public func showSecondaryButton() { - if secondaryButton.superview == nil { - stack.addArrangedSubview(secondaryButton) + if !stack.arrangedSubviews.contains(secondaryButton) { + stack.insertArrangedSubview(secondaryButton, at: 0) secondaryButton.isHidden = false } if primaryButton.superview != nil { From 23e87b1cbb9e4e1da83ec987ad22f170dcb48422 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 6 Feb 2020 12:44:25 -0500 Subject: [PATCH 15/57] removed caveman code. --- .../Molecules/VerticalCombinationViews/HeadlineBody.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBody.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBody.swift index 8226dfc1..b94adef0 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBody.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBody.swift @@ -135,9 +135,6 @@ open class HeadlineBody: View { style(with: headlineBodyModel.style) - print("Headline -H: \(headlineBodyModel.headline?.text ?? "~nada~")") - print("Headline -B: \(headlineBodyModel.body?.text ?? "~nada~")") - headlineLabel.setWithModel(headlineBodyModel.headline, delegateObject, additionalData) messageLabel.setWithModel(headlineBodyModel.body, delegateObject, additionalData) } From 0dad2aedb1b7610faa9b3cacb256071309296ff4 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 6 Feb 2020 13:00:55 -0500 Subject: [PATCH 16/57] type fix --- MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift b/MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift index fa7548f3..689a7c62 100644 --- a/MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift +++ b/MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift @@ -41,7 +41,7 @@ import Foundation screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading) isAtomicTabs = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAtomicTabs) header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header) - header = try typeContainer.decodeMoleculeIfPresent(codingKey: .middle) + middle = try typeContainer.decodeMoleculeIfPresent(codingKey: .middle) footer = try typeContainer.decodeMoleculeIfPresent(codingKey: .footer) } From 61a5932a886c5c8bc27a0ff9e4c9ef7ee3c7acf1 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 6 Feb 2020 13:25:52 -0500 Subject: [PATCH 17/57] fixing bug where textfield was not being recognized when resigning responder. --- .../Atoms/TextFields/BaseDropdownEntryField.swift | 2 +- MVMCoreUI/Atoms/TextFields/TextEntryField.swift | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Atoms/TextFields/BaseDropdownEntryField.swift b/MVMCoreUI/Atoms/TextFields/BaseDropdownEntryField.swift index 3290c744..70b46866 100644 --- a/MVMCoreUI/Atoms/TextFields/BaseDropdownEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/BaseDropdownEntryField.swift @@ -21,7 +21,7 @@ import UIKit let caret = CaretView() caret.direction = .down caret.lineWidth = 1.5 - caret.isUserInteractionEnabled = true + caret.isUserInteractionEnabled = false caret.heightAnchor.constraint(equalToConstant: 9).isActive = true caret.widthAnchor.constraint(equalToConstant: 16).isActive = true return caret diff --git a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift index 66f3ecd4..def2ae0b 100644 --- a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift @@ -25,7 +25,7 @@ import UIKit //-------------------------------------------------- open private(set) var textField: TextField = { - let textField = TextField(frame: .zero) + let textField = TextField() textField.isAccessibilityElement = true textField.setContentCompressionResistancePriority(.required, for: .vertical) textField.font = MFStyler.fontForTextField() @@ -58,7 +58,7 @@ import UIKit get { return super.isEnabled } set (enabled) { super.isEnabled = enabled - + DispatchQueue.main.async { [weak self] in guard let self = self else { return } @@ -99,7 +99,7 @@ import UIKit //-------------------------------------------------- public var validationBlock: ((_ value: String?) -> Bool)? - + //-------------------------------------------------- // MARK: - Delegate Properties //-------------------------------------------------- @@ -169,6 +169,9 @@ import UIKit textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 16) textFieldTrailingConstraint?.isActive = true + textField.addTarget(self, action: #selector(startEditing), for: .editingDidBegin) + textField.addTarget(self, action: #selector(dismissFieldInput(_:)), for: .editingDidEnd) + let tap = UITapGestureRecognizer(target: self, action: #selector(startEditing)) entryFieldContainer.addGestureRecognizer(tap) @@ -225,7 +228,7 @@ import UIKit /// Validates the text of the entry field. @discardableResult @objc public func validateTextField() -> Bool { - + isValid = validationBlock?(text) ?? true if isValid { @@ -277,7 +280,7 @@ import UIKit guard let model = model as? TextEntryFieldModel else { return } FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol) - + textColor.enabled = model.enabledTextColor?.uiColor textColor.disabled = model.disabledTextColor?.uiColor text = model.text From 3eb94fe616fcbf86b73ea37a2a0dfca1d3f9cd46 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 7 Feb 2020 09:11:06 -0500 Subject: [PATCH 18/57] removing print statements. --- MVMCoreUI/Templates/MoleculeListTemplate.swift | 4 ---- 1 file changed, 4 deletions(-) diff --git a/MVMCoreUI/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Templates/MoleculeListTemplate.swift index f9319927..a088d34a 100644 --- a/MVMCoreUI/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeListTemplate.swift @@ -197,8 +197,6 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } } - print("ADD PATHS: \(indexPaths)") - self.tableView?.insertRows(at: indexPaths, with: animation) self.updateViewConstraints() self.view.layoutIfNeeded() @@ -227,8 +225,6 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } } - print("REMOVE PATHS: \(indexPaths)") - tableView?.deleteRows(at: indexPaths, with: animation) updateViewConstraints() view.layoutIfNeeded() From bf8ea963b0c4c486ff5cb427ea3ce83baea0069c Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 7 Feb 2020 15:29:58 -0500 Subject: [PATCH 19/57] bring back view controller --- MVMCoreUI.xcodeproj/project.pbxproj | 6 +- .../BaseControllers/ViewController.swift | 83 +++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 MVMCoreUI/BaseControllers/ViewController.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index f97e81aa..8812759f 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -307,6 +307,7 @@ D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2B1E3E422F37D6A0065F95C /* ImageHeadlineBody.swift */; }; D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */; }; + D2C521A923EDE79E00CA2634 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2C521A823EDE79E00CA2634 /* ViewController.swift */; }; D2D6CD4022E78C1A00D701B8 /* Scroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */; }; D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */; }; D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */; }; @@ -637,6 +638,7 @@ D2B1E3E422F37D6A0065F95C /* ImageHeadlineBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageHeadlineBody.swift; sourceTree = ""; }; D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewControllerMappingObject.h; sourceTree = ""; }; D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIViewControllerMappingObject.m; sourceTree = ""; }; + D2C521A823EDE79E00CA2634 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scroller.swift; sourceTree = ""; }; D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerTemplate.swift; sourceTree = ""; }; D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUIDelegateObject.swift; sourceTree = ""; }; @@ -651,7 +653,6 @@ D2E2A99E23E07F8A000B42E6 /* PillButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillButton.swift; sourceTree = ""; }; D2E2A9A023E095AB000B42E6 /* ButtonModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonModelProtocol.swift; sourceTree = ""; }; D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableableModelProtocol.swift; sourceTree = ""; }; - D2F4DDE52371A4CB00CD28BB /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeContainer.swift; sourceTree = ""; }; D2FB151C23A40F1500C20E10 /* MoleculeStackItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackItem.swift; sourceTree = ""; }; DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeftRightLabelView.swift; sourceTree = ""; }; @@ -1079,7 +1080,7 @@ D29DF2CD21E7C104003B2FB9 /* MFLoadingViewController.m */, D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */, D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */, - D2F4DDE52371A4CB00CD28BB /* ViewController.swift */, + D2C521A823EDE79E00CA2634 /* ViewController.swift */, ); path = BaseControllers; sourceTree = ""; @@ -1719,6 +1720,7 @@ D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */, 0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */, D243859923A16B1800332775 /* Container.swift in Sources */, + D2C521A923EDE79E00CA2634 /* ViewController.swift in Sources */, D260105B23D0BB7100764D80 /* StackModelProtocol.swift in Sources */, D29DF29821E7ADB8003B2FB9 /* MFScrollingViewController.m in Sources */, D28A839323CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift in Sources */, diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift new file mode 100644 index 00000000..8202378b --- /dev/null +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -0,0 +1,83 @@ +// +// ViewController.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 11/5/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers open class ViewController: UIViewController, MVMCoreViewControllerProtocol { + public var pageType: String? + public var loadObject: MVMCoreLoadObject? + public var pageModel: PageModelProtocol? + + // MARK: Response handling + public func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer) -> Bool { + pageType = loadObject.pageType + self.loadObject = loadObject + + // Parse the model for the page. + do { + try parsePageJSON() + } catch let parsingError { + // Log all parsing errors and fail load. + if let errorObject = MVMCoreErrorObject.createErrorObject(for: parsingError, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject)) { + errorObject.messageToDisplay = MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess) + error.pointee = errorObject + } + return false + } + + // Verifies all modules needed are loaded. + return MFViewController.verifyRequiredModulesLoaded(for: loadObject, error: error) + } + + @objc func parsePageJSON() throws { + } + + public class func verifyRequiredModulesLoaded(for loadObject: MVMCoreLoadObject?, error: inout MVMCoreErrorObject?) -> Bool { + guard let pageType = loadObject?.pageType, var modulesRequired = MVMCoreUIViewControllerMappingObject.shared()?.modulesRequired(forPageType: pageType) else { return true } + + guard let loadedModules = loadObject?.modulesJSON else { return false } + + for case let key as String in Array(loadedModules.keys) { + guard modulesRequired.count > 0 else { break } + if let index = modulesRequired.firstIndex(where: {($0 as? String) == key}), index != NSNotFound { + modulesRequired.remove(at: index) + } + } + + guard modulesRequired.count == 0 else { + if error != nil { + error = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorCritical), messageToLog: modulesRequired.description, code: ErrorCode.requiredModuleNotPresent.rawValue, domain: ErrorDomainNative, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject!)) + } + return false + } + return true + } + + open func setNavigationItem() { + navigationItem.title = pageModel?.screenHeading + navigationItem.accessibilityLabel = pageModel?.screenHeading + + } + + open func newDataBuildScreen() { + // TODO atomize the navigation item + setNavigationItem() + } + + open func initialLoad() { + } + + open func updateViews() { + } + + override open func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } +} From 593bae7820b676f2ddfcbf6d3b52b063b8c4a5cb Mon Sep 17 00:00:00 2001 From: Subhankar Acharya Date: Mon, 10 Feb 2020 11:49:03 +0530 Subject: [PATCH 20/57] Molecule-ThreeColumnPlanDataDividerList --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ++ .../ThreeColumnPlanDataDividerList.swift | 91 +++++++++++++++++++ .../ThreeColumnPlanDataDividerListModel.swift | 52 +++++++++++ .../OtherHandlers/MoleculeObjectMapping.swift | 2 + 4 files changed, 153 insertions(+) create mode 100644 MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerList.swift create mode 100644 MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerListModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index a35514cb..1ca8be9b 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -95,6 +95,8 @@ 0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; }; 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; }; 31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; }; + 52DD6C6B23E97B040011ECB2 /* ThreeColumnPlanDataDividerListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DD6C6A23E97B040011ECB2 /* ThreeColumnPlanDataDividerListModel.swift */; }; + 52DD6C6D23E97B5E0011ECB2 /* ThreeColumnPlanDataDividerList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DD6C6C23E97B5E0011ECB2 /* ThreeColumnPlanDataDividerList.swift */; }; 9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; }; 943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; }; 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; }; @@ -408,6 +410,8 @@ 0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = ""; }; 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = ""; }; 31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = ""; }; + 52DD6C6A23E97B040011ECB2 /* ThreeColumnPlanDataDividerListModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeColumnPlanDataDividerListModel.swift; sourceTree = ""; }; + 52DD6C6C23E97B5E0011ECB2 /* ThreeColumnPlanDataDividerList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeColumnPlanDataDividerList.swift; sourceTree = ""; }; 9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = ""; }; 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = ""; }; 943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = ""; }; @@ -873,6 +877,8 @@ D28A837E23CCA96400DFE4FC /* TabsModel.swift */, 94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */, 94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */, + 52DD6C6A23E97B040011ECB2 /* ThreeColumnPlanDataDividerListModel.swift */, + 52DD6C6C23E97B5E0011ECB2 /* ThreeColumnPlanDataDividerList.swift */, ); path = HorizontalCombinationViews; sourceTree = ""; @@ -1636,6 +1642,7 @@ 0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */, 94FB966323D797DA003D482B /* MFTextButton.m in Sources */, D260105323CEA61600764D80 /* ToggleModel.swift in Sources */, + 52DD6C6B23E97B040011ECB2 /* ThreeColumnPlanDataDividerListModel.swift in Sources */, 014AA72523C501E2006F3E93 /* ContainerModel.swift in Sources */, 0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */, D29DF2EF21ECEAE1003B2FB9 /* MFFonts.m in Sources */, @@ -1714,6 +1721,7 @@ D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */, 0A21DB83235DFBC500C160A2 /* MdnEntryField.swift in Sources */, D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */, + 52DD6C6D23E97B5E0011ECB2 /* ThreeColumnPlanDataDividerList.swift in Sources */, 012A88C6238DA34000FE3DA1 /* ModuleMoleculeModel.swift in Sources */, 94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */, D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */, diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerList.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerList.swift new file mode 100644 index 00000000..1624095c --- /dev/null +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerList.swift @@ -0,0 +1,91 @@ +// +// ThreeColumnPlanDataDividerList.swift +// MVMCoreUI +// +// Created by Acharya, Subhankar on 04/02/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class ThreeColumnPlanDataDividerList: TableViewCell { + + let leftHeadlineBody = HeadlineBody(frame: .zero) + let centerHeadLineBody = HeadlineBody(frame: .zero) + let rightHeadLineBody = HeadlineBody(frame: .zero) + let containerView = ViewConstrainingView() + let betweenHeadlineBodyPaddingConstant: CGFloat = 18.0 + let headlineBodyTopPaddingConstant: CGFloat = 48.0 + let containerViewPaddingConstant: CGFloat = 30.0 + + // MARK: - Initialization + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + setupView() + } + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + // MARK: - MFViewProtocol + open override func updateView(_ size: CGFloat) { + super.updateView(size) + containerView.updateView(size) + leftHeadlineBody.updateView(size) + centerHeadLineBody.updateView(size) + rightHeadLineBody.updateView(size) + } + open override func setupView() { + super.setupView() + selectionStyle = .default + guard leftHeadlineBody.superview == nil else { + return + } + containerView.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(containerView) + contentView.heightAnchor.constraint(greaterThanOrEqualToConstant: 103.0).isActive = true + containerView.pinView(toSuperView: contentView) + containerView.addSubview(leftHeadlineBody) + containerView.addSubview(centerHeadLineBody) + containerView.addSubview(rightHeadLineBody) + //width calculation of headlinebody + let constraint = rightHeadLineBody.widthAnchor.constraint(equalTo: containerView.widthAnchor, multiplier: 0.25) + constraint.isActive = true + rightHeadLineBody.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal) + centerHeadLineBody.widthAnchor.constraint(equalTo: rightHeadLineBody.widthAnchor).isActive = true + leftHeadlineBody.widthAnchor.constraint(equalTo: rightHeadLineBody.widthAnchor).isActive = true + //Constraints of headlinebody to superview + leftHeadlineBody.topAnchor.constraint(equalTo: containerView.topAnchor, constant: headlineBodyTopPaddingConstant).isActive = true + centerHeadLineBody.topAnchor.constraint(equalTo: containerView.topAnchor, constant: headlineBodyTopPaddingConstant).isActive = true + rightHeadLineBody.topAnchor.constraint(equalTo: containerView.topAnchor, constant: headlineBodyTopPaddingConstant).isActive = true + + containerView.bottomAnchor.constraint(equalTo: leftHeadlineBody.bottomAnchor).isActive = true + containerView.bottomAnchor.constraint(equalTo: centerHeadLineBody.bottomAnchor).isActive = true + containerView.bottomAnchor.constraint(equalTo: rightHeadLineBody.bottomAnchor).isActive = true + + leftHeadlineBody.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: containerViewPaddingConstant).isActive = true + centerHeadLineBody.leadingAnchor.constraint(equalTo: leftHeadlineBody.trailingAnchor, constant: betweenHeadlineBodyPaddingConstant).isActive = true + rightHeadLineBody.leadingAnchor.constraint(equalTo: centerHeadLineBody.trailingAnchor, constant: betweenHeadlineBodyPaddingConstant).isActive = true + rightHeadLineBody.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -containerViewPaddingConstant).isActive = true + + } + // MARK: - MVMCoreUIMoleculeViewProtocol + public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.setWithModel(model, delegateObject, additionalData) + guard let model = model as? ThreeColumnPlanDataDividerListModel else { return } + leftHeadlineBody.setWithModel(model.leftHeadlineBody, delegateObject, additionalData) + centerHeadLineBody.setWithModel(model.centerHeadlineBody, delegateObject, additionalData) + centerHeadLineBody.isHidden = model.centerHeadlineBody == nil + rightHeadLineBody.setWithModel(model.rightHeadlineBody, delegateObject, additionalData) + } + open override func reset() { + super.reset() + containerView.reset() + leftHeadlineBody.reset() + centerHeadLineBody.reset() + rightHeadLineBody.reset() + } + public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 103 + } +} + diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerListModel.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerListModel.swift new file mode 100644 index 00000000..b9a94288 --- /dev/null +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerListModel.swift @@ -0,0 +1,52 @@ +// +// ThreeColumnPlanDataDividerListModel.swift +// MVMCoreUI +// +// Created by Acharya, Subhankar on 04/02/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +public class ThreeColumnPlanDataDividerListModel: ContainerModel, ListItemModelProtocol { + public var hideArrow: Bool? + public var style: String? + public var line: LineModel? + public var backgroundColor: Color? + public static var identifier: String = "list3CHBDiv" + public var leftHeadlineBody: HeadlineBodyModel + public var centerHeadlineBody: HeadlineBodyModel? + public var rightHeadlineBody: HeadlineBodyModel + + init(leftheadlineBody: HeadlineBodyModel, rightHeadLineBody: HeadlineBodyModel) { + self.leftHeadlineBody = leftheadlineBody + self.rightHeadlineBody = rightHeadLineBody + super.init() + } + private enum CodingKeys: String, CodingKey { + case style + case moleculeName + case leftHeadlineBody + case centerHeadlineBody + case rightHeadlineBody + } + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + style = try typeContainer.decodeIfPresent(String.self, forKey: .style) + leftHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .leftHeadlineBody) + centerHeadlineBody = try typeContainer.decodeIfPresent(HeadlineBodyModel.self, forKey: .centerHeadlineBody) + rightHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .rightHeadlineBody) + 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.encode(ThreeColumnPlanDataDividerListModel.identifier, forKey: .moleculeName) + try container.encode(leftHeadlineBody, forKey: .leftHeadlineBody) + try container.encodeIfPresent(centerHeadlineBody, forKey: .centerHeadlineBody) + try container.encode(rightHeadlineBody, forKey: .rightHeadlineBody) + } + +} + diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index d3523ccf..cbfacbb7 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -55,6 +55,8 @@ import Foundation // Horizontal Combination Molecules MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ThreeColumnPlanDataDividerList.self, viewModelClass: ThreeColumnPlanDataDividerListModel.self) + // Vertical Combination Molecules MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self) From c94a440008a53977e4bd286aba9ba461b442a648 Mon Sep 17 00:00:00 2001 From: Subhankar Acharya Date: Mon, 10 Feb 2020 11:54:45 +0530 Subject: [PATCH 21/57] ThreeColumnPlanDataDividerList reference file --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index f97e81aa..e11334c6 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -95,6 +95,8 @@ 0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; }; 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; }; 31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; }; + 5248BFEC23F12E350059236A /* ThreeColumnPlanDataDividerList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5248BFEA23F12E350059236A /* ThreeColumnPlanDataDividerList.swift */; }; + 5248BFED23F12E350059236A /* ThreeColumnPlanDataDividerListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5248BFEB23F12E350059236A /* ThreeColumnPlanDataDividerListModel.swift */; }; 9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; }; 943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; }; 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; }; @@ -412,6 +414,8 @@ 0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = ""; }; 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = ""; }; 31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = ""; }; + 5248BFEA23F12E350059236A /* ThreeColumnPlanDataDividerList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThreeColumnPlanDataDividerList.swift; sourceTree = ""; }; + 5248BFEB23F12E350059236A /* ThreeColumnPlanDataDividerListModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThreeColumnPlanDataDividerListModel.swift; sourceTree = ""; }; 9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = ""; }; 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = ""; }; 943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = ""; }; @@ -880,6 +884,8 @@ D224798E2316A995003FCCF9 /* HorizontalCombinationViews */ = { isa = PBXGroup; children = ( + 5248BFEA23F12E350059236A /* ThreeColumnPlanDataDividerList.swift */, + 5248BFEB23F12E350059236A /* ThreeColumnPlanDataDividerListModel.swift */, D2E2A99B23D8D975000B42E6 /* ImageHeadlineBodyModel.swift */, D2B1E3E422F37D6A0065F95C /* ImageHeadlineBody.swift */, D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */, @@ -1541,6 +1547,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5248BFED23F12E350059236A /* ThreeColumnPlanDataDividerListModel.swift in Sources */, 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */, 943784F5236B77BB006A1E82 /* GraphView.swift in Sources */, 31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */, @@ -1638,6 +1645,7 @@ 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */, D260105523CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift in Sources */, D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */, + 5248BFEC23F12E350059236A /* ThreeColumnPlanDataDividerList.swift in Sources */, 0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */, 0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */, 94F217B723E0BF6100A47C06 /* PrimaryButtonView.m in Sources */, From 66f0cf6b8e2bc428302d1dea1055c1911588c0d3 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Tue, 11 Feb 2020 08:39:09 +0530 Subject: [PATCH 22/57] Modified code based on review comments Molecule class conforming to TableViewCell instead of Container. Model class conforming to ListItemModelProtocol instead of MoleculeModelProtocol Removed extra spaces and added comments --- .../LeftVariableIconRightCaretList.swift | 77 ++++++++++++------- .../LeftVariableIconRightCaretListModel.swift | 49 ++++++++---- 2 files changed, 80 insertions(+), 46 deletions(-) diff --git a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift index f7b08220..c35678a2 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift @@ -9,24 +9,40 @@ import Foundation import UIKit -@objcMembers public class LeftVariableIconRightCaretList : Container { +@objcMembers public class LeftVariableIconRightCaretList: TableViewCell { //----------------------------------------------------- // MARK: - Outlets //------------------------------------------------------- let leftImage = MFLoadImageView() - let leftLabel = Label(frame: .zero) - let rightLabel = Label(frame: .zero) - + let leftLabel = Label.commonLabelB2(true) + let rightLabel = Label.commonLabelB2(true) + let containerView = ViewConstrainingView() //------------------------------------------------------ // MARK: - Properties - //------------------------------------------------------- - let spaceBetweenLabels : CGFloat = 180 - let horizontalPadding : CGFloat = 14 - let imageSize : CGFloat = 30 + //------------------------------------------------------ + let cellHeight: CGFloat = 79 + let leftPadding: CGFloat = 35 + let spaceBetweenImageAndLeftLabel: CGFloat = 16 + let imageSize: CGFloat = 30 + let spaceBetweenLabels: CGFloat = 40 + let rightPadding: CGFloat = 54 + + //------------------------------------------------------ + // MARK: - Initialization + //-------------------------------------------------------- + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + setupView() + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } //----------------------------------------------------- // MARK: - View Lifecycle @@ -34,10 +50,10 @@ import UIKit open override func updateView(_ size: CGFloat) { super.updateView(size) + containerView.updateView(size) leftImage.updateView(size) leftLabel.updateView(size) rightLabel.updateView(size) - } override open func setupView() { @@ -45,30 +61,36 @@ import UIKit guard leftImage.superview == nil else { return } + containerView.translatesAutoresizingMaskIntoConstraints = false + contentView.heightAnchor.constraint(equalToConstant: cellHeight).isActive = true + contentView.addSubview(containerView) - let container = MVMCoreUICommonViewsUtility.commonView() + //containerView constraints + containerView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true + containerView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true + containerView.topAnchor.constraint(equalTo: topAnchor).isActive = true + containerView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true - addAndContain(container) - container.addSubview(leftImage) - container.addSubview(leftLabel) - container.addSubview(rightLabel) + containerView.addSubview(leftImage) + containerView.addSubview(leftLabel) + containerView.addSubview(rightLabel) - self.translatesAutoresizingMaskIntoConstraints = false - - leftImage.leadingAnchor.constraint(equalTo: container.leadingAnchor).isActive = true - leftImage.topAnchor.constraint(equalTo: container.topAnchor).isActive = true - leftImage.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true + //leftImage constraints + leftImage.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: leftPadding).isActive = true + leftImage.centerYAnchor.constraint(equalTo: leftLabel.centerYAnchor).isActive = true leftImage.widthAnchor.constraint(equalToConstant: imageSize).isActive = true leftImage.heightAnchor.constraint(equalToConstant: imageSize).isActive = true - leftLabel.leadingAnchor.constraint(equalTo: leftImage.trailingAnchor, constant: horizontalPadding).isActive = true - leftLabel.topAnchor.constraint(equalTo: container.topAnchor).isActive = true - leftLabel.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true + //leftLabel constraints + leftLabel.leadingAnchor.constraint(equalTo: leftImage.trailingAnchor, constant: spaceBetweenImageAndLeftLabel).isActive = true + leftLabel.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true + leftLabel.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true - - rightLabel.leadingAnchor.constraint(equalTo: leftLabel.trailingAnchor,constant: spaceBetweenLabels).isActive = true - rightLabel.topAnchor.constraint(equalTo: container.topAnchor).isActive = true - rightLabel.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true + //rightLabel constraints + rightLabel.leadingAnchor.constraint(greaterThanOrEqualTo: leftLabel.trailingAnchor, constant: spaceBetweenLabels).isActive = true + rightLabel.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true + rightLabel.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true + containerView.trailingAnchor.constraint(equalTo: rightLabel.trailingAnchor,constant: rightPadding).isActive = true } //---------------------------------------------------- @@ -77,17 +99,14 @@ import UIKit override open func reset() { super.reset() - leftImage.reset() leftLabel.reset() rightLabel.reset() } public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) guard let model = model as? LeftVariableIconRightCaretListModel else { return} - leftImage.setWithModel(model.image, delegateObject, additionalData) leftLabel.setWithModel(model.leftLabel, delegateObject, additionalData) rightLabel.setWithModel(model.rightLabel, delegateObject, additionalData) diff --git a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift index 152f8128..dab0b153 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift @@ -8,31 +8,38 @@ import Foundation -public class LeftVariableIconRightCaretListModel: MoleculeModelProtocol { +public class LeftVariableIconRightCaretListModel: ContainerModel, ListItemModelProtocol { - public var horizontalAlignment: UIStackView.Alignment? - public var verticalAlignment: UIStackView.Alignment? - public var useHorizontalMargins: Bool? - public var useVerticalMargins: Bool? - public var topMarginPadding: CGFloat? - public var bottomMarginPadding: CGFloat? - - - public var line: LineModel? = LineModel(type: .standard) - public var hideArrow: Bool? + public var line: LineModel? + public var hideArrow: Bool? = false public var backgroundColor: Color? - + public var action: ActionModelProtocol? public static var identifier: String = "listLVImg" public var image: ImageViewModel public var leftLabel: LabelModel public var rightLabel: LabelModel - + func setDefaults() { + if useHorizontalMargins == nil { + useHorizontalMargins = true + } + if useVerticalMargins == nil { + useVerticalMargins = true + } + if topMarginPadding == nil { + topMarginPadding = 24 + } + if bottomMarginPadding == nil { + bottomMarginPadding = 0 + } + } public init(image: ImageViewModel, leftLabel: LabelModel, rightLabel: LabelModel) { self.image = image self.leftLabel = leftLabel self.rightLabel = rightLabel + super.init() + setDefaults() } private enum CodingKeys: String, CodingKey { @@ -40,6 +47,8 @@ public class LeftVariableIconRightCaretListModel: MoleculeModelProtocol { case leftLabel case rightLabel case image + case action + case hideArrow } required public init(from decoder: Decoder) throws { @@ -47,16 +56,22 @@ public class LeftVariableIconRightCaretListModel: MoleculeModelProtocol { leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel) rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) image = try typeContainer.decode(ImageViewModel.self, forKey: .image) + action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType) + hideArrow = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideArrow) + try super.init(from: decoder) + setDefaults() } - - public func encode(to encoder: Encoder) throws { + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(LeftVariableIconRightCaretListModel.identifier, forKey: .moleculeName) try container.encode(leftLabel, forKey: .leftLabel) try container.encode(rightLabel, forKey: .rightLabel) - try container.encodeIfPresent(image, forKey: .image) + try container.encode(image, forKey: .image) + try container.encodeModelIfPresent(action, forKey: .action) + try container.encodeIfPresent(hideArrow, forKey: .hideArrow) } - } + From 965dcf538b5239929f94dab4b6df0705dafbde50 Mon Sep 17 00:00:00 2001 From: Kruthika KP <> Date: Tue, 11 Feb 2020 12:18:45 +0530 Subject: [PATCH 23/57] Class naming convention changed and removed init methods where not required. --- MVMCoreUI.xcodeproj/project.pbxproj | 16 ++++++------ ... ListLeftVariableIconWithRightCaret.swift} | 26 +++++-------------- ...LeftVariableIconWithRightCaretModel.swift} | 10 +++---- .../OtherHandlers/MoleculeObjectMapping.swift | 2 +- 4 files changed, 18 insertions(+), 36 deletions(-) rename MVMCoreUI/Molecules/LeftRightViews/{LeftVariableIconRightCaretList.swift => ListLeftVariableIconWithRightCaret.swift} (83%) rename MVMCoreUI/Molecules/LeftRightViews/{LeftVariableIconRightCaretListModel.swift => ListLeftVariableIconWithRightCaretModel.swift} (83%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index e17401e0..e02f3542 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -95,8 +95,8 @@ 0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; }; 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; }; 31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; }; - 8D24041123E7FB9E009E23BE /* LeftVariableIconRightCaretList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041023E7FB9E009E23BE /* LeftVariableIconRightCaretList.swift */; }; - 8D24041523E7FC0B009E23BE /* LeftVariableIconRightCaretListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041423E7FC0B009E23BE /* LeftVariableIconRightCaretListModel.swift */; }; + 8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */; }; + 8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */; }; 9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; }; 943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; }; 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; }; @@ -414,8 +414,8 @@ 0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = ""; }; 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = ""; }; 31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = ""; }; - 8D24041023E7FB9E009E23BE /* LeftVariableIconRightCaretList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftVariableIconRightCaretList.swift; sourceTree = ""; }; - 8D24041423E7FC0B009E23BE /* LeftVariableIconRightCaretListModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftVariableIconRightCaretListModel.swift; sourceTree = ""; }; + 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaret.swift; sourceTree = ""; }; + 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretModel.swift; sourceTree = ""; }; 9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = ""; }; 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = ""; }; 943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = ""; }; @@ -897,8 +897,8 @@ isa = PBXGroup; children = ( D2E2A99723D8D63C000B42E6 /* ActionDetailWithImageModel.swift */, - 8D24041023E7FB9E009E23BE /* LeftVariableIconRightCaretList.swift */, - 8D24041423E7FC0B009E23BE /* LeftVariableIconRightCaretListModel.swift */, + 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */, + 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */, 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */, D28A839023CD4FD400DFE4FC /* CornerLabelsModel.swift */, 01509D902327ECE600EF99AA /* CornerLabels.swift */, @@ -1694,7 +1694,7 @@ 94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, - 8D24041523E7FC0B009E23BE /* LeftVariableIconRightCaretListModel.swift in Sources */, + 8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */, D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */, 012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */, D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */, @@ -1707,7 +1707,7 @@ D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */, D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */, 0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */, - 8D24041123E7FB9E009E23BE /* LeftVariableIconRightCaretList.swift in Sources */, + 8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */, D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */, DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */, 0A21DB89235E06EF00C160A2 /* MFMdnTextField.m in Sources */, diff --git a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift similarity index 83% rename from MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift rename to MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift index c35678a2..7a6ac9be 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretList.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift @@ -1,5 +1,5 @@ // -// LeftVariableIconRightCaretList.swift +// ListLeftVariableIconWithRightCaret.swift // MVMCoreUI // // Created by Kruthika KP on 03/02/20. @@ -9,7 +9,7 @@ import Foundation import UIKit -@objcMembers public class LeftVariableIconRightCaretList: TableViewCell { +@objcMembers public class ListLeftVariableIconWithRightCaret: TableViewCell { //----------------------------------------------------- // MARK: - Outlets @@ -18,7 +18,7 @@ import UIKit let leftImage = MFLoadImageView() let leftLabel = Label.commonLabelB2(true) let rightLabel = Label.commonLabelB2(true) - let containerView = ViewConstrainingView() + let containerView = Container() //------------------------------------------------------ // MARK: - Properties @@ -29,21 +29,7 @@ import UIKit let spaceBetweenImageAndLeftLabel: CGFloat = 16 let imageSize: CGFloat = 30 let spaceBetweenLabels: CGFloat = 40 - let rightPadding: CGFloat = 54 - - //------------------------------------------------------ - // MARK: - Initialization - //-------------------------------------------------------- - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - setupView() - } - - required public init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - } - + //----------------------------------------------------- // MARK: - View Lifecycle //------------------------------------------------------- @@ -90,7 +76,7 @@ import UIKit rightLabel.leadingAnchor.constraint(greaterThanOrEqualTo: leftLabel.trailingAnchor, constant: spaceBetweenLabels).isActive = true rightLabel.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true rightLabel.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true - containerView.trailingAnchor.constraint(equalTo: rightLabel.trailingAnchor,constant: rightPadding).isActive = true + containerView.trailingAnchor.constraint(equalTo: rightLabel.trailingAnchor,constant: PaddingNine).isActive = true } //---------------------------------------------------- @@ -106,7 +92,7 @@ import UIKit public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.setWithModel(model, delegateObject, additionalData) - guard let model = model as? LeftVariableIconRightCaretListModel else { return} + guard let model = model as? ListLeftVariableIconWithRightCaretModel else { return} leftImage.setWithModel(model.image, delegateObject, additionalData) leftLabel.setWithModel(model.leftLabel, delegateObject, additionalData) rightLabel.setWithModel(model.rightLabel, delegateObject, additionalData) diff --git a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaretModel.swift similarity index 83% rename from MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift rename to MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaretModel.swift index dab0b153..b29affb8 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/LeftVariableIconRightCaretListModel.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaretModel.swift @@ -1,5 +1,5 @@ // -// LeftVariableIconRightCaretListModel.swift +// ListLeftVariableIconWithRightCaretModel.swift // MVMCoreUI // // Created by Kruthika KP on 03/02/20. @@ -8,7 +8,7 @@ import Foundation -public class LeftVariableIconRightCaretListModel: ContainerModel, ListItemModelProtocol { +public class ListLeftVariableIconWithRightCaretModel: ContainerModel, ListItemModelProtocol { public var line: LineModel? public var hideArrow: Bool? = false @@ -39,7 +39,6 @@ public class LeftVariableIconRightCaretListModel: ContainerModel, ListItemModelP self.leftLabel = leftLabel self.rightLabel = rightLabel super.init() - setDefaults() } private enum CodingKeys: String, CodingKey { @@ -48,7 +47,6 @@ public class LeftVariableIconRightCaretListModel: ContainerModel, ListItemModelP case rightLabel case image case action - case hideArrow } required public init(from decoder: Decoder) throws { @@ -57,7 +55,6 @@ public class LeftVariableIconRightCaretListModel: ContainerModel, ListItemModelP rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) image = try typeContainer.decode(ImageViewModel.self, forKey: .image) action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType) - hideArrow = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideArrow) try super.init(from: decoder) setDefaults() } @@ -65,12 +62,11 @@ public class LeftVariableIconRightCaretListModel: ContainerModel, ListItemModelP public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(LeftVariableIconRightCaretListModel.identifier, forKey: .moleculeName) + try container.encode(ListLeftVariableIconWithRightCaretModel.identifier, forKey: .moleculeName) try container.encode(leftLabel, forKey: .leftLabel) try container.encode(rightLabel, forKey: .rightLabel) try container.encode(image, forKey: .image) try container.encodeModelIfPresent(action, forKey: .action) - try container.encodeIfPresent(hideArrow, forKey: .hideArrow) } } diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index a87dac90..34af5083 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -70,7 +70,7 @@ import Foundation MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyToggle.self, viewModelClass: HeadlineBodyToggleModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeadlineBodyLinkToggle.self, viewModelClass: HeadlineBodyLinkToggleModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ActionDetailWithImage.self, viewModelClass: ActionDetailWithImageModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: LeftVariableIconRightCaretList.self, viewModelClass: LeftVariableIconRightCaretListModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListLeftVariableIconWithRightCaret.self, viewModelClass: ListLeftVariableIconWithRightCaretModel.self) // List items MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeTableViewCell.self, viewModelClass: ListItemModel.self) From 05aaac573da65c1c83d502c023ad64cebba39646 Mon Sep 17 00:00:00 2001 From: Subhankar Acharya Date: Tue, 11 Feb 2020 17:30:34 +0530 Subject: [PATCH 24/57] Code checkin after changing way of implementation. --- MVMCoreUI.xcodeproj/project.pbxproj | 16 ++--- .../ListThreeColumnPlanDataDivider.swift | 67 +++++++++++++++++++ .../ListThreeColumnPlanDataDividerModel.swift | 52 ++++++++++++++ .../OtherHandlers/MoleculeObjectMapping.swift | 2 +- 4 files changed, 128 insertions(+), 9 deletions(-) create mode 100644 MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift create mode 100644 MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDividerModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index e11334c6..23257a31 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -95,8 +95,8 @@ 0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; }; 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; }; 31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; }; - 5248BFEC23F12E350059236A /* ThreeColumnPlanDataDividerList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5248BFEA23F12E350059236A /* ThreeColumnPlanDataDividerList.swift */; }; - 5248BFED23F12E350059236A /* ThreeColumnPlanDataDividerListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5248BFEB23F12E350059236A /* ThreeColumnPlanDataDividerListModel.swift */; }; + 5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5248BFEA23F12E350059236A /* ListThreeColumnPlanDataDivider.swift */; }; + 5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */; }; 9432A79F23DB47BA00719041 /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */; }; 943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; }; 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; }; @@ -414,8 +414,8 @@ 0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = ""; }; 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = ""; }; 31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = ""; }; - 5248BFEA23F12E350059236A /* ThreeColumnPlanDataDividerList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThreeColumnPlanDataDividerList.swift; sourceTree = ""; }; - 5248BFEB23F12E350059236A /* ThreeColumnPlanDataDividerListModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThreeColumnPlanDataDividerListModel.swift; sourceTree = ""; }; + 5248BFEA23F12E350059236A /* ListThreeColumnPlanDataDivider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnPlanDataDivider.swift; sourceTree = ""; }; + 5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnPlanDataDividerModel.swift; sourceTree = ""; }; 9402C34F23A2CEA3004B974C /* LeftRightLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftRightLabelModel.swift; sourceTree = ""; }; 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = ""; }; 943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = ""; }; @@ -884,8 +884,8 @@ D224798E2316A995003FCCF9 /* HorizontalCombinationViews */ = { isa = PBXGroup; children = ( - 5248BFEA23F12E350059236A /* ThreeColumnPlanDataDividerList.swift */, - 5248BFEB23F12E350059236A /* ThreeColumnPlanDataDividerListModel.swift */, + 5248BFEA23F12E350059236A /* ListThreeColumnPlanDataDivider.swift */, + 5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */, D2E2A99B23D8D975000B42E6 /* ImageHeadlineBodyModel.swift */, D2B1E3E422F37D6A0065F95C /* ImageHeadlineBody.swift */, D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */, @@ -1547,7 +1547,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5248BFED23F12E350059236A /* ThreeColumnPlanDataDividerListModel.swift in Sources */, + 5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */, 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */, 943784F5236B77BB006A1E82 /* GraphView.swift in Sources */, 31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */, @@ -1645,7 +1645,7 @@ 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */, D260105523CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift in Sources */, D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */, - 5248BFEC23F12E350059236A /* ThreeColumnPlanDataDividerList.swift in Sources */, + 5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */, 0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */, 0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */, 94F217B723E0BF6100A47C06 /* PrimaryButtonView.m in Sources */, diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift new file mode 100644 index 00000000..c34c7a55 --- /dev/null +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift @@ -0,0 +1,67 @@ +// +// ThreeColumnPlanDataDividerList.swift +// MVMCoreUI +// +// Created by Acharya, Subhankar on 04/02/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class ListThreeColumnPlanDataDivider: TableViewCell { + + let leftHeadlineBody = HeadlineBody(frame: .zero) + let centerHeadLineBody = HeadlineBody(frame: .zero) + let rightHeadLineBody = HeadlineBody(frame: .zero) + private var stack = UIStackView() + + // MARK: - MFViewProtocol + open override func updateView(_ size: CGFloat) { + super.updateView(size) + leftHeadlineBody.updateView(size) + centerHeadLineBody.updateView(size) + rightHeadLineBody.updateView(size) + } + + open override func setupView() { + super.setupView() + guard leftHeadlineBody.superview == nil else { + return + } + //using stackView to align the three headlineBody + stack.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(stack) + stack.addArrangedSubview(leftHeadlineBody) + stack.addArrangedSubview(centerHeadLineBody) + stack.addArrangedSubview(rightHeadLineBody) + NSLayoutConstraint.constraintPinSubview(stack, pinTop: true, topConstant: 0, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: PaddingDefaultHorizontalSpacing, pinRight: true, rightConstant: PaddingDefaultHorizontalSpacing) + stack.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true + stack.axis = .horizontal + stack.spacing = 35 + stack.distribution = .fillProportionally + styleTallDivider() + } + + // MARK: - MVMCoreUIMoleculeViewProtocol + public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.setWithModel(model, delegateObject, additionalData) + guard let model = model as? ListThreeColumnPlanDataDividerModel else { return } + leftHeadlineBody.setWithModel(model.leftHeadlineBody, delegateObject, additionalData) + centerHeadLineBody.setWithModel(model.centerHeadlineBody, delegateObject, additionalData) + rightHeadLineBody.setWithModel(model.rightHeadlineBody, delegateObject, additionalData) + } + + open override func reset() { + super.reset() + styleTallDivider() + leftHeadlineBody.reset() + centerHeadLineBody.reset() + rightHeadLineBody.reset() + } + + public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 103 + } + +} + diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDividerModel.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDividerModel.swift new file mode 100644 index 00000000..0da1499d --- /dev/null +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDividerModel.swift @@ -0,0 +1,52 @@ +// +// ThreeColumnPlanDataDividerListModel.swift +// MVMCoreUI +// +// Created by Acharya, Subhankar on 04/02/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +public class ListThreeColumnPlanDataDividerModel: ContainerModel, ListItemModelProtocol { + public var hideArrow: Bool? + public var style: String? = "tallDivider" + public var line: LineModel? + public var backgroundColor: Color? + public static var identifier: String = "list3CHBDiv" + public var leftHeadlineBody: HeadlineBodyModel + public var centerHeadlineBody: HeadlineBodyModel + public var rightHeadlineBody: HeadlineBodyModel + + public init(leftHeadlineBody: HeadlineBodyModel, centerHeadlineBody:HeadlineBodyModel, rightHeadlineBody: HeadlineBodyModel) { + self.leftHeadlineBody = leftHeadlineBody + self.centerHeadlineBody = centerHeadlineBody + self.rightHeadlineBody = rightHeadlineBody + super.init() + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case leftHeadlineBody + case centerHeadlineBody + case rightHeadlineBody + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + leftHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .leftHeadlineBody) + centerHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .centerHeadlineBody) + rightHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .rightHeadlineBody) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(leftHeadlineBody, forKey: .leftHeadlineBody) + try container.encode(centerHeadlineBody, forKey: .centerHeadlineBody) + try container.encode(rightHeadlineBody, forKey: .rightHeadlineBody) + } +} + diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index b029b352..94407366 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -55,7 +55,7 @@ import Foundation // Horizontal Combination Molecules MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ThreeColumnPlanDataDividerList.self, viewModelClass: ThreeColumnPlanDataDividerListModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListThreeColumnPlanDataDivider.self, viewModelClass: ListThreeColumnPlanDataDividerModel.self) // Vertical Combination Molecules From fb65f9e9765576ac6957ed11f4249a2f7f207d2e Mon Sep 17 00:00:00 2001 From: Subhankar Acharya Date: Tue, 11 Feb 2020 17:31:28 +0530 Subject: [PATCH 25/57] Deleted the files after changing naming convention. --- .../ThreeColumnPlanDataDividerList.swift | 91 ------------------- .../ThreeColumnPlanDataDividerListModel.swift | 52 ----------- 2 files changed, 143 deletions(-) delete mode 100644 MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerList.swift delete mode 100644 MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerListModel.swift diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerList.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerList.swift deleted file mode 100644 index 1624095c..00000000 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerList.swift +++ /dev/null @@ -1,91 +0,0 @@ -// -// ThreeColumnPlanDataDividerList.swift -// MVMCoreUI -// -// Created by Acharya, Subhankar on 04/02/20. -// Copyright © 2020 Verizon Wireless. All rights reserved. -// - -import Foundation - -@objcMembers open class ThreeColumnPlanDataDividerList: TableViewCell { - - let leftHeadlineBody = HeadlineBody(frame: .zero) - let centerHeadLineBody = HeadlineBody(frame: .zero) - let rightHeadLineBody = HeadlineBody(frame: .zero) - let containerView = ViewConstrainingView() - let betweenHeadlineBodyPaddingConstant: CGFloat = 18.0 - let headlineBodyTopPaddingConstant: CGFloat = 48.0 - let containerViewPaddingConstant: CGFloat = 30.0 - - // MARK: - Initialization - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - setupView() - } - required public init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - } - // MARK: - MFViewProtocol - open override func updateView(_ size: CGFloat) { - super.updateView(size) - containerView.updateView(size) - leftHeadlineBody.updateView(size) - centerHeadLineBody.updateView(size) - rightHeadLineBody.updateView(size) - } - open override func setupView() { - super.setupView() - selectionStyle = .default - guard leftHeadlineBody.superview == nil else { - return - } - containerView.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(containerView) - contentView.heightAnchor.constraint(greaterThanOrEqualToConstant: 103.0).isActive = true - containerView.pinView(toSuperView: contentView) - containerView.addSubview(leftHeadlineBody) - containerView.addSubview(centerHeadLineBody) - containerView.addSubview(rightHeadLineBody) - //width calculation of headlinebody - let constraint = rightHeadLineBody.widthAnchor.constraint(equalTo: containerView.widthAnchor, multiplier: 0.25) - constraint.isActive = true - rightHeadLineBody.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal) - centerHeadLineBody.widthAnchor.constraint(equalTo: rightHeadLineBody.widthAnchor).isActive = true - leftHeadlineBody.widthAnchor.constraint(equalTo: rightHeadLineBody.widthAnchor).isActive = true - //Constraints of headlinebody to superview - leftHeadlineBody.topAnchor.constraint(equalTo: containerView.topAnchor, constant: headlineBodyTopPaddingConstant).isActive = true - centerHeadLineBody.topAnchor.constraint(equalTo: containerView.topAnchor, constant: headlineBodyTopPaddingConstant).isActive = true - rightHeadLineBody.topAnchor.constraint(equalTo: containerView.topAnchor, constant: headlineBodyTopPaddingConstant).isActive = true - - containerView.bottomAnchor.constraint(equalTo: leftHeadlineBody.bottomAnchor).isActive = true - containerView.bottomAnchor.constraint(equalTo: centerHeadLineBody.bottomAnchor).isActive = true - containerView.bottomAnchor.constraint(equalTo: rightHeadLineBody.bottomAnchor).isActive = true - - leftHeadlineBody.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: containerViewPaddingConstant).isActive = true - centerHeadLineBody.leadingAnchor.constraint(equalTo: leftHeadlineBody.trailingAnchor, constant: betweenHeadlineBodyPaddingConstant).isActive = true - rightHeadLineBody.leadingAnchor.constraint(equalTo: centerHeadLineBody.trailingAnchor, constant: betweenHeadlineBodyPaddingConstant).isActive = true - rightHeadLineBody.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -containerViewPaddingConstant).isActive = true - - } - // MARK: - MVMCoreUIMoleculeViewProtocol - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - super.setWithModel(model, delegateObject, additionalData) - guard let model = model as? ThreeColumnPlanDataDividerListModel else { return } - leftHeadlineBody.setWithModel(model.leftHeadlineBody, delegateObject, additionalData) - centerHeadLineBody.setWithModel(model.centerHeadlineBody, delegateObject, additionalData) - centerHeadLineBody.isHidden = model.centerHeadlineBody == nil - rightHeadLineBody.setWithModel(model.rightHeadlineBody, delegateObject, additionalData) - } - open override func reset() { - super.reset() - containerView.reset() - leftHeadlineBody.reset() - centerHeadLineBody.reset() - rightHeadLineBody.reset() - } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { - return 103 - } -} - diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerListModel.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerListModel.swift deleted file mode 100644 index b9a94288..00000000 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/ThreeColumnPlanDataDividerListModel.swift +++ /dev/null @@ -1,52 +0,0 @@ -// -// ThreeColumnPlanDataDividerListModel.swift -// MVMCoreUI -// -// Created by Acharya, Subhankar on 04/02/20. -// Copyright © 2020 Verizon Wireless. All rights reserved. -// - -import UIKit - -public class ThreeColumnPlanDataDividerListModel: ContainerModel, ListItemModelProtocol { - public var hideArrow: Bool? - public var style: String? - public var line: LineModel? - public var backgroundColor: Color? - public static var identifier: String = "list3CHBDiv" - public var leftHeadlineBody: HeadlineBodyModel - public var centerHeadlineBody: HeadlineBodyModel? - public var rightHeadlineBody: HeadlineBodyModel - - init(leftheadlineBody: HeadlineBodyModel, rightHeadLineBody: HeadlineBodyModel) { - self.leftHeadlineBody = leftheadlineBody - self.rightHeadlineBody = rightHeadLineBody - super.init() - } - private enum CodingKeys: String, CodingKey { - case style - case moleculeName - case leftHeadlineBody - case centerHeadlineBody - case rightHeadlineBody - } - required public init(from decoder: Decoder) throws { - let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - style = try typeContainer.decodeIfPresent(String.self, forKey: .style) - leftHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .leftHeadlineBody) - centerHeadlineBody = try typeContainer.decodeIfPresent(HeadlineBodyModel.self, forKey: .centerHeadlineBody) - rightHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .rightHeadlineBody) - 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.encode(ThreeColumnPlanDataDividerListModel.identifier, forKey: .moleculeName) - try container.encode(leftHeadlineBody, forKey: .leftHeadlineBody) - try container.encodeIfPresent(centerHeadlineBody, forKey: .centerHeadlineBody) - try container.encode(rightHeadlineBody, forKey: .rightHeadlineBody) - } - -} - From d5ac7e3e6dabc7957e58c40f9ce0f2654f928890 Mon Sep 17 00:00:00 2001 From: Subhankar Acharya Date: Tue, 11 Feb 2020 17:33:12 +0530 Subject: [PATCH 26/57] removed line break --- .../ListThreeColumnPlanDataDivider.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift index c34c7a55..0dadc8fa 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift @@ -62,6 +62,5 @@ import Foundation public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { return 103 } - } From d92c5b5679b8ccce8b7ae26cf240e47d34fd36bb Mon Sep 17 00:00:00 2001 From: Subhankar Acharya Date: Tue, 11 Feb 2020 22:21:07 +0530 Subject: [PATCH 27/57] Code changes using the StackModel --- .../ListThreeColumnPlanDataDivider.swift | 32 ++++++++----------- .../Molecules/Items/StackItemModel.swift | 5 +++ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift index 0dadc8fa..9e821f25 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift @@ -13,14 +13,13 @@ import Foundation let leftHeadlineBody = HeadlineBody(frame: .zero) let centerHeadLineBody = HeadlineBody(frame: .zero) let rightHeadLineBody = HeadlineBody(frame: .zero) - private var stack = UIStackView() + let stack = Stack(frame: .zero) // MARK: - MFViewProtocol open override func updateView(_ size: CGFloat) { super.updateView(size) - leftHeadlineBody.updateView(size) - centerHeadLineBody.updateView(size) - rightHeadLineBody.updateView(size) + styleTallDivider() + stack.updateView(size) } open override func setupView() { @@ -28,18 +27,11 @@ import Foundation guard leftHeadlineBody.superview == nil else { return } - //using stackView to align the three headlineBody + //using stackItems to align the three headlineBody stack.translatesAutoresizingMaskIntoConstraints = false + stack.stackItems = [StackItem(andContain: leftHeadlineBody),StackItem(andContain: centerHeadLineBody),StackItem(andContain: rightHeadLineBody)] contentView.addSubview(stack) - stack.addArrangedSubview(leftHeadlineBody) - stack.addArrangedSubview(centerHeadLineBody) - stack.addArrangedSubview(rightHeadLineBody) - NSLayoutConstraint.constraintPinSubview(stack, pinTop: true, topConstant: 0, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: PaddingDefaultHorizontalSpacing, pinRight: true, rightConstant: PaddingDefaultHorizontalSpacing) - stack.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true - stack.axis = .horizontal - stack.spacing = 35 - stack.distribution = .fillProportionally - styleTallDivider() + containerHelper.constrainView(stack) } // MARK: - MVMCoreUIMoleculeViewProtocol @@ -49,14 +41,18 @@ import Foundation leftHeadlineBody.setWithModel(model.leftHeadlineBody, delegateObject, additionalData) centerHeadLineBody.setWithModel(model.centerHeadlineBody, delegateObject, additionalData) rightHeadLineBody.setWithModel(model.rightHeadlineBody, delegateObject, additionalData) + + // Create a stack model to use for the internal stack. + let stackModel = StackModel(molecules: [StackItemModel(percent: 33),StackItemModel(percent: 33),StackItemModel(percent: 33)]) + stackModel.spacing = 0 + stackModel.axis = .horizontal + stack.model = stackModel + stack.restack() } open override func reset() { super.reset() - styleTallDivider() - leftHeadlineBody.reset() - centerHeadLineBody.reset() - rightHeadLineBody.reset() + stack.reset() } public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { diff --git a/MVMCoreUI/Molecules/Items/StackItemModel.swift b/MVMCoreUI/Molecules/Items/StackItemModel.swift index f296986e..66c57809 100644 --- a/MVMCoreUI/Molecules/Items/StackItemModel.swift +++ b/MVMCoreUI/Molecules/Items/StackItemModel.swift @@ -19,4 +19,9 @@ import Foundation self.init() self.gone = gone } + + public convenience init(percent: Int) { + self.init() + self.percent = percent + } } From fed9b8ff92187f4c6a5a277c397ae8de25382963 Mon Sep 17 00:00:00 2001 From: Kruthika KP <> Date: Wed, 12 Feb 2020 16:45:09 +0530 Subject: [PATCH 28/57] added default horizontal padding --- .../LeftRightViews/ListLeftVariableIconWithRightCaret.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift index 7a6ac9be..43a3b5da 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift @@ -29,6 +29,7 @@ import UIKit let spaceBetweenImageAndLeftLabel: CGFloat = 16 let imageSize: CGFloat = 30 let spaceBetweenLabels: CGFloat = 40 + let horizontalPadding = MFStyler.defaultHorizontalPaddingForApplicationWidth() //----------------------------------------------------- // MARK: - View Lifecycle @@ -62,11 +63,12 @@ import UIKit containerView.addSubview(rightLabel) //leftImage constraints - leftImage.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: leftPadding).isActive = true + leftImage.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: horizontalPadding).isActive = true leftImage.centerYAnchor.constraint(equalTo: leftLabel.centerYAnchor).isActive = true leftImage.widthAnchor.constraint(equalToConstant: imageSize).isActive = true leftImage.heightAnchor.constraint(equalToConstant: imageSize).isActive = true + //leftLabel constraints leftLabel.leadingAnchor.constraint(equalTo: leftImage.trailingAnchor, constant: spaceBetweenImageAndLeftLabel).isActive = true leftLabel.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true @@ -76,7 +78,7 @@ import UIKit rightLabel.leadingAnchor.constraint(greaterThanOrEqualTo: leftLabel.trailingAnchor, constant: spaceBetweenLabels).isActive = true rightLabel.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true rightLabel.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true - containerView.trailingAnchor.constraint(equalTo: rightLabel.trailingAnchor,constant: PaddingNine).isActive = true + rightLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor,constant: -horizontalPadding - 20).isActive = true } //---------------------------------------------------- From 394a5aba18a52dc8f87a04442c9860173e1df136 Mon Sep 17 00:00:00 2001 From: Subhankar Acharya Date: Wed, 12 Feb 2020 21:34:47 +0530 Subject: [PATCH 29/57] Code fixes for alignment and StackItemModel conformance change. --- .../ListThreeColumnPlanDataDivider.swift | 12 ++++++++---- .../ListThreeColumnPlanDataDividerModel.swift | 12 ++++++++++++ MVMCoreUI/Molecules/Items/StackItemModel.swift | 2 +- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift index 9e821f25..84361c9c 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDivider.swift @@ -18,7 +18,6 @@ import Foundation // MARK: - MFViewProtocol open override func updateView(_ size: CGFloat) { super.updateView(size) - styleTallDivider() stack.updateView(size) } @@ -42,9 +41,14 @@ import Foundation centerHeadLineBody.setWithModel(model.centerHeadlineBody, delegateObject, additionalData) rightHeadLineBody.setWithModel(model.rightHeadlineBody, delegateObject, additionalData) - // Create a stack model to use for the internal stack. - let stackModel = StackModel(molecules: [StackItemModel(percent: 33),StackItemModel(percent: 33),StackItemModel(percent: 33)]) - stackModel.spacing = 0 + // Create a stack model to use for the internal stack and set the alignment of models + let leftHeadlineBodyAlignment = StackItemModel(percent: 33) + leftHeadlineBodyAlignment.horizontalAlignment = .leading + let centerHeadLineBodyAlignment = StackItemModel(percent: 34) + centerHeadLineBodyAlignment.horizontalAlignment = .center + let rightHeadLineBodyAlignment = StackItemModel(percent: 33) + rightHeadLineBodyAlignment.horizontalAlignment = .trailing + let stackModel = StackModel(molecules: [leftHeadlineBodyAlignment,centerHeadLineBodyAlignment,rightHeadLineBodyAlignment]) stackModel.axis = .horizontal stack.model = stackModel stack.restack() diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDividerModel.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDividerModel.swift index 0da1499d..d03d8528 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDividerModel.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/ListThreeColumnPlanDataDividerModel.swift @@ -23,6 +23,17 @@ public class ListThreeColumnPlanDataDividerModel: ContainerModel, ListItemModelP self.centerHeadlineBody = centerHeadlineBody self.rightHeadlineBody = rightHeadlineBody super.init() + setDefaults() + } + + /// Defaults to set + func setDefaults() { + if useHorizontalMargins == nil { + useHorizontalMargins = true + } + if useVerticalMargins == nil { + useVerticalMargins = true + } } private enum CodingKeys: String, CodingKey { @@ -38,6 +49,7 @@ public class ListThreeColumnPlanDataDividerModel: ContainerModel, ListItemModelP centerHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .centerHeadlineBody) rightHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .rightHeadlineBody) try super.init(from: decoder) + setDefaults() } public override func encode(to encoder: Encoder) throws { diff --git a/MVMCoreUI/Molecules/Items/StackItemModel.swift b/MVMCoreUI/Molecules/Items/StackItemModel.swift index 66c57809..2058353c 100644 --- a/MVMCoreUI/Molecules/Items/StackItemModel.swift +++ b/MVMCoreUI/Molecules/Items/StackItemModel.swift @@ -8,7 +8,7 @@ import Foundation -@objcMembers public class StackItemModel: StackItemModelProtocol, MoleculeModelProtocol { +@objcMembers public class StackItemModel: ContainerModel, StackItemModelProtocol, MoleculeModelProtocol { public static var identifier: String = "simpleStackItem" public var backgroundColor: Color? public var spacing: CGFloat? From e0bb0e45dc7f177ec13bff0cb9b2e7dae6230c1c Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 12 Feb 2020 11:25:37 -0500 Subject: [PATCH 30/57] integrating changes to make fan out instance models into categories due to name conflicts --- .../Atoms/Views/CircleProgressModel.swift | 1 + .../Label/LabelAttributeColorModel.swift | 14 ++++++-- .../Views/Label/LabelAttributeFontModel.swift | 19 +++++++++-- .../Label/LabelAttributeImageModel.swift | 19 ++++++++--- .../Views/Label/LabelAttributeModel.swift | 26 ++++++++++++--- .../MFViewController+Model.swift | 32 ++++++++----------- .../Extensions/MoleculeModelHelper.swift | 4 ++- .../CarouselItemModelProtocol.swift | 5 +-- .../CarouselPagingModelProtocol.swift | 3 +- .../ContainerModelProtocol.swift | 1 + .../DisableableModelProtocol.swift | 1 + .../ModelProtocols/FormModelProtocol.swift | 1 + .../ListItemModelProtocol.swift | 19 +++++++++-- .../MoleculeModelProtocol.swift | 17 ++++++++-- .../ModelProtocols/PageModelProtocol.swift | 18 +++++++++++ .../TemplateModelProtocol.swift | 6 ++-- ...MoleculeMappingObject+ModelExtension.swift | 2 +- .../OtherHandlers/MoleculeObjectMapping.swift | 17 +++++----- .../Templates/ListPageTemplateModel.swift | 17 +++++++++- MVMCoreUI/Templates/TemplateProtocol.swift | 1 + 20 files changed, 169 insertions(+), 54 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/CircleProgressModel.swift b/MVMCoreUI/Atoms/Views/CircleProgressModel.swift index feb69083..c4f55bef 100644 --- a/MVMCoreUI/Atoms/Views/CircleProgressModel.swift +++ b/MVMCoreUI/Atoms/Views/CircleProgressModel.swift @@ -17,6 +17,7 @@ public enum GraphStyle: String, Codable { } public class CircleProgressModel: MoleculeModelProtocol { + public static var identifier: String = "circleProgress" public var style: GraphStyle = .unlimited { didSet { diff --git a/MVMCoreUI/Atoms/Views/Label/LabelAttributeColorModel.swift b/MVMCoreUI/Atoms/Views/Label/LabelAttributeColorModel.swift index 26f1fa54..01183614 100644 --- a/MVMCoreUI/Atoms/Views/Label/LabelAttributeColorModel.swift +++ b/MVMCoreUI/Atoms/Views/Label/LabelAttributeColorModel.swift @@ -9,6 +9,9 @@ import UIKit @objcMembers public class LabelAttributeColorModel: LabelAttributeModel { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- override public class var identifier: String { return "color" @@ -16,14 +19,21 @@ import UIKit var textColor: String? + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case textColor } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { - let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - self.textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor) + textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor) try super.init(from: decoder) } diff --git a/MVMCoreUI/Atoms/Views/Label/LabelAttributeFontModel.swift b/MVMCoreUI/Atoms/Views/Label/LabelAttributeFontModel.swift index 88ae728d..2e9e6e1c 100644 --- a/MVMCoreUI/Atoms/Views/Label/LabelAttributeFontModel.swift +++ b/MVMCoreUI/Atoms/Views/Label/LabelAttributeFontModel.swift @@ -8,7 +8,12 @@ import UIKit + @objcMembers public class LabelAttributeFontModel: LabelAttributeModel { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + override public class var identifier: String { return "font" } @@ -17,17 +22,25 @@ import UIKit var name: String? var size: CGFloat? + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case style case name case size } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + 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) + style = try typeContainer.decodeIfPresent(String.self, forKey: .style) + name = try typeContainer.decodeIfPresent(String.self, forKey: .name) + size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size) try super.init(from: decoder) } diff --git a/MVMCoreUI/Atoms/Views/Label/LabelAttributeImageModel.swift b/MVMCoreUI/Atoms/Views/Label/LabelAttributeImageModel.swift index 0095a589..1980353c 100644 --- a/MVMCoreUI/Atoms/Views/Label/LabelAttributeImageModel.swift +++ b/MVMCoreUI/Atoms/Views/Label/LabelAttributeImageModel.swift @@ -9,7 +9,10 @@ import UIKit class LabelAttributeImageModel: LabelAttributeModel { - + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + override public class var identifier: String { return "image" } @@ -18,17 +21,25 @@ class LabelAttributeImageModel: LabelAttributeModel { var name: String? var URL: String? + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case size case name case URL } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + 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) + size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size) + name = try typeContainer.decodeIfPresent(String.self, forKey: .name) + URL = try typeContainer.decodeIfPresent(String.self, forKey: .URL) try super.init(from: decoder) } diff --git a/MVMCoreUI/Atoms/Views/Label/LabelAttributeModel.swift b/MVMCoreUI/Atoms/Views/Label/LabelAttributeModel.swift index ae2768ab..22bb10d8 100644 --- a/MVMCoreUI/Atoms/Views/Label/LabelAttributeModel.swift +++ b/MVMCoreUI/Atoms/Views/Label/LabelAttributeModel.swift @@ -9,6 +9,17 @@ import Foundation @objcMembers open class LabelAttributeModel: Model { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public static var categoryName: String { + return "\(LabelAttributeModel.self)" + } + + public static var categoryCodingKey: String { + return "type" + } public class var identifier: String { return "" @@ -18,17 +29,25 @@ import Foundation var location: Int var length: Int + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case type case location case length } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + 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) + type = try typeContainer.decode(String.self, forKey: .type) + location = try typeContainer.decode(Int.self, forKey: .location) + length = try typeContainer.decode(Int.self, forKey: .length) } public func encode(to encoder: Encoder) throws { @@ -37,5 +56,4 @@ import Foundation try container.encode(location, forKey: .location) try container.encode(length, forKey: .length) } - } diff --git a/MVMCoreUI/BaseControllers/MFViewController+Model.swift b/MVMCoreUI/BaseControllers/MFViewController+Model.swift index 6cedf93c..1c58c574 100644 --- a/MVMCoreUI/BaseControllers/MFViewController+Model.swift +++ b/MVMCoreUI/BaseControllers/MFViewController+Model.swift @@ -9,41 +9,35 @@ import Foundation extension MFViewController: MoleculeDelegateProtocol { - public func getModuleWithName(_ name: String?) -> [AnyHashable : Any]? { - guard let name = name else { - return nil - } + + public func getModuleWithName(_ name: String?) -> [AnyHashable: Any]? { + guard let name = name else { return nil } + return loadObject?.modulesJSON?.optionalDictionaryForKey(name) } public func getModuleWithName(_ moduleName: String) -> MoleculeModelProtocol? { guard let moduleJSON = loadObject?.modulesJSON?.optionalDictionaryForKey(moduleName), let moleculeName = moduleJSON.optionalStringForKey("moleculeName"), - let modelType = ModelRegistry.getType(for: moleculeName) as? MoleculeModelProtocol.Type else { - return nil - } + let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self) + else { return nil } + do { - return try modelType.decode(jsonDict: moduleJSON) + return try modelType.decode(jsonDict: moduleJSON) as? MoleculeModelProtocol } catch { MVMCoreUILoggingHandler.logDebugMessage(withDelegate: "error: \(error)") } + return nil } - @objc public func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) { - - } + @objc public func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) { } - @objc public func addMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { - // Do nothing - } + @objc public func addMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { } - @objc public func removeMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { - // Do nothing - } + @objc public func removeMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { } } public extension MFViewController { - @objc func parsePageJSON() throws { - } + @objc func parsePageJSON() throws { } } diff --git a/MVMCoreUI/Models/Extensions/MoleculeModelHelper.swift b/MVMCoreUI/Models/Extensions/MoleculeModelHelper.swift index 599851bb..87460640 100644 --- a/MVMCoreUI/Models/Extensions/MoleculeModelHelper.swift +++ b/MVMCoreUI/Models/Extensions/MoleculeModelHelper.swift @@ -8,7 +8,9 @@ import Foundation -extension KeyedDecodingContainer where Key : CodingKey { + +extension KeyedDecodingContainer where Key: CodingKey { + private enum TypeCodingKey: String, CodingKey { case moleculeName } diff --git a/MVMCoreUI/Models/ModelProtocols/CarouselItemModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/CarouselItemModelProtocol.swift index 53a6cc10..093c9337 100644 --- a/MVMCoreUI/Models/ModelProtocols/CarouselItemModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/CarouselItemModelProtocol.swift @@ -8,7 +8,8 @@ import Foundation + public protocol CarouselItemModelProtocol: ContainerModelProtocol, MoleculeModelProtocol { - var peakingUI: Bool? {get} - var peakingArrowColor: Color? {get} + var peakingUI: Bool? { get } + var peakingArrowColor: Color? { get } } diff --git a/MVMCoreUI/Models/ModelProtocols/CarouselPagingModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/CarouselPagingModelProtocol.swift index 5f593d3b..94b1277a 100644 --- a/MVMCoreUI/Models/ModelProtocols/CarouselPagingModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/CarouselPagingModelProtocol.swift @@ -8,6 +8,7 @@ import Foundation + public protocol CarouselPagingModelProtocol: MoleculeModelProtocol { - var position: Float? {get} + var position: Float? { get } } diff --git a/MVMCoreUI/Models/ModelProtocols/ContainerModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/ContainerModelProtocol.swift index 304a4811..bc230731 100644 --- a/MVMCoreUI/Models/ModelProtocols/ContainerModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/ContainerModelProtocol.swift @@ -8,6 +8,7 @@ import Foundation + public protocol ContainerModelProtocol { var horizontalAlignment: UIStackView.Alignment? { get set } var verticalAlignment: UIStackView.Alignment? { get set } diff --git a/MVMCoreUI/Models/ModelProtocols/DisableableModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/DisableableModelProtocol.swift index 1e49bd8c..db0cfd77 100644 --- a/MVMCoreUI/Models/ModelProtocols/DisableableModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/DisableableModelProtocol.swift @@ -8,6 +8,7 @@ import Foundation + public protocol EnableableModelProtocol { var enabled: Bool { get set } } diff --git a/MVMCoreUI/Models/ModelProtocols/FormModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/FormModelProtocol.swift index aa298716..1224d5a9 100644 --- a/MVMCoreUI/Models/ModelProtocols/FormModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/FormModelProtocol.swift @@ -8,6 +8,7 @@ import Foundation + public protocol FormModelProtocol: Model { var required: Bool? { get } var fieldKey: String? { get } diff --git a/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift index c6be0488..cd19a23c 100644 --- a/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift @@ -8,6 +8,7 @@ import Foundation + public protocol ListItemModelProtocol: ContainerModelProtocol, MoleculeModelProtocol { var line: LineModel? { get set } var action: ActionModelProtocol? { get set } @@ -16,15 +17,27 @@ public protocol ListItemModelProtocol: ContainerModelProtocol, MoleculeModelProt } // Not a strict requirement. -extension ListItemModelProtocol { +public extension ListItemModelProtocol { - public var action: ActionModelProtocol? { + var action: ActionModelProtocol? { get { return nil } set { } } - public var style: String? { + var style: String? { get { return nil } set { } } + + var moleculeName: String? { + get { return Self.identifier } + } + + var categoryName: String { + return "\(ListItemModelProtocol.self)" + } + +// var categoryCodingKey: String { +// return "style" +// } } diff --git a/MVMCoreUI/Models/ModelProtocols/MoleculeModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/MoleculeModelProtocol.swift index 85a91bcd..9f099331 100644 --- a/MVMCoreUI/Models/ModelProtocols/MoleculeModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/MoleculeModelProtocol.swift @@ -1,12 +1,25 @@ import Foundation + public protocol MoleculeModelProtocol: Model { var moleculeName: String? { get } var backgroundColor: Color? { get set} + + static var categoryName: String { get } + static var categoryCodingKey: String { get } } -extension MoleculeModelProtocol { - public var moleculeName: String? { +public extension MoleculeModelProtocol { + + var moleculeName: String? { get { return Self.identifier } } + + static var categoryName: String { + return "\(MoleculeModelProtocol.self)" + } + + static var categoryCodingKey: String { + return "moleculeName" + } } diff --git a/MVMCoreUI/Models/ModelProtocols/PageModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/PageModelProtocol.swift index 8c6d1557..2ad9b8a2 100644 --- a/MVMCoreUI/Models/ModelProtocols/PageModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/PageModelProtocol.swift @@ -8,8 +8,26 @@ import Foundation + public protocol PageModelProtocol: Model { var pageType: String { get set } var screenHeading: String? { get set } var isAtomicTabs: Bool? { get set } + + static var categoryName: String { get } + static var categoryCodingKey: String { get } +} + +extension PageModelProtocol { + //TODO: Scott implement + + public static var categoryCodingKey: String { + return "moleculeName" + } + + public static var categoryName: String { + return "\(PageModelProtocol.self)" + } +// public static var categoryName: String { return "template" } +// public static var categoryCodingKey: String { return "\(PageModelProtocol.self)" } } diff --git a/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift index 66472da6..90a8ec2a 100644 --- a/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift @@ -8,12 +8,14 @@ import Foundation + public protocol TemplateModelProtocol: PageModelProtocol { var template: String { get } } -extension TemplateModelProtocol { - public var template: String { +public extension TemplateModelProtocol { + + var template: String { get { return Self.identifier } } } diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelExtension.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelExtension.swift index 4796b2a2..6249e61e 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelExtension.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject+ModelExtension.swift @@ -11,7 +11,7 @@ import Foundation public extension MVMCoreUIMoleculeMappingObject { func register(viewClass: V.Type, viewModelClass: M.Type) { - ModelRegistry.register(viewModelClass) + try? ModelRegistry.register(viewModelClass) MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(viewClass, forKey: viewModelClass.identifier as NSString) } diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index 8c1a36e3..b139f33b 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -18,13 +18,13 @@ import Foundation // Label MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Label.self, viewModelClass: LabelModel.self) - //need to move labelattributemodel to different method - ModelRegistry.register(LabelAttributeFontModel.self) - ModelRegistry.register(LabelAttributeColorModel.self) - //ModelRegistry.register(LabelAttributeImageModel.self) // We need to separate the registry by types due to collisions... - ModelRegistry.register(LabelAttributeUnderlineModel.self) - ModelRegistry.register(LabelAttributeStrikeThroughModel.self) - ModelRegistry.register(LabelAttributeActionModel.self) + // need to move labelattributemodel to different method + try? ModelRegistry.register(LabelAttributeFontModel.self) + try? ModelRegistry.register(LabelAttributeColorModel.self) + try? ModelRegistry.register(LabelAttributeImageModel.self) // We need to separate the registry by types due to collisions... + try? ModelRegistry.register(LabelAttributeUnderlineModel.self) + try? ModelRegistry.register(LabelAttributeStrikeThroughModel.self) + try? ModelRegistry.register(LabelAttributeActionModel.self) // Buttons MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self) @@ -40,7 +40,6 @@ import Foundation MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: DateDropdownEntryField.self, viewModelClass: DateDropdownEntryFieldModel.self) // Other Atoms - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Label.self, viewModelClass: LabelModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CaretView.self, viewModelClass: CaretViewModel.self) @@ -104,6 +103,6 @@ import Foundation MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(MVMCoreUIPageControl.self, forKey: "barsPager" as NSString) // TODO: Need View - ModelRegistry.register(TabsModel.self) + try? ModelRegistry.register(TabsModel.self) } } diff --git a/MVMCoreUI/Templates/ListPageTemplateModel.swift b/MVMCoreUI/Templates/ListPageTemplateModel.swift index fe9c12c5..ff899319 100644 --- a/MVMCoreUI/Templates/ListPageTemplateModel.swift +++ b/MVMCoreUI/Templates/ListPageTemplateModel.swift @@ -9,7 +9,10 @@ import Foundation @objcMembers public class ListPageTemplateModel: TemplateModelProtocol { - + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "list" public var pageType: String @@ -21,12 +24,20 @@ import Foundation public var footer: MoleculeModelProtocol? public var line: LineModel? + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(pageType: String, screenHeading: String?, molecules: [ListItemModelProtocol]) { self.pageType = pageType self.screenHeading = screenHeading self.molecules = molecules } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case pageType @@ -38,6 +49,10 @@ import Foundation case isAtomicTabs } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) pageType = try typeContainer.decode(String.self, forKey: .pageType) diff --git a/MVMCoreUI/Templates/TemplateProtocol.swift b/MVMCoreUI/Templates/TemplateProtocol.swift index 0498ec5d..63c66263 100644 --- a/MVMCoreUI/Templates/TemplateProtocol.swift +++ b/MVMCoreUI/Templates/TemplateProtocol.swift @@ -14,6 +14,7 @@ public protocol TemplateProtocol: class { } public extension TemplateProtocol where Self: MFViewController { + func parseTemplateJSON() throws { guard let pageJSON = self.loadObject?.pageJSON else { return } let data = try JSONSerialization.data(withJSONObject: pageJSON) From c30a0012394b1b1f855243e62817872532aa643d Mon Sep 17 00:00:00 2001 From: Subhankar Acharya Date: Wed, 12 Feb 2020 23:01:02 +0530 Subject: [PATCH 31/57] Code Changes after reimplementing the molecule class. --- .../Molecules/Items/StackItemModel.swift | 2 +- .../ListLeftVariableIconWithRightCaret.swift | 70 ++++++------------- ...tLeftVariableIconWithRightCaretModel.swift | 8 +-- 3 files changed, 25 insertions(+), 55 deletions(-) diff --git a/MVMCoreUI/Molecules/Items/StackItemModel.swift b/MVMCoreUI/Molecules/Items/StackItemModel.swift index f296986e..9d193f17 100644 --- a/MVMCoreUI/Molecules/Items/StackItemModel.swift +++ b/MVMCoreUI/Molecules/Items/StackItemModel.swift @@ -8,7 +8,7 @@ import Foundation -@objcMembers public class StackItemModel: StackItemModelProtocol, MoleculeModelProtocol { +@objcMembers public class StackItemModel: ContainerModel, StackItemModelProtocol, MoleculeModelProtocol { public static var identifier: String = "simpleStackItem" public var backgroundColor: Color? public var spacing: CGFloat? diff --git a/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift index 43a3b5da..9cdf9cee 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift @@ -14,30 +14,15 @@ import UIKit //----------------------------------------------------- // MARK: - Outlets //------------------------------------------------------- - let leftImage = MFLoadImageView() let leftLabel = Label.commonLabelB2(true) let rightLabel = Label.commonLabelB2(true) - let containerView = Container() - - //------------------------------------------------------ - // MARK: - Properties - //------------------------------------------------------ - - let cellHeight: CGFloat = 79 - let leftPadding: CGFloat = 35 - let spaceBetweenImageAndLeftLabel: CGFloat = 16 - let imageSize: CGFloat = 30 - let spaceBetweenLabels: CGFloat = 40 - let horizontalPadding = MFStyler.defaultHorizontalPaddingForApplicationWidth() - + let stack = Stack(frame: .zero) //----------------------------------------------------- // MARK: - View Lifecycle //------------------------------------------------------- - open override func updateView(_ size: CGFloat) { super.updateView(size) - containerView.updateView(size) leftImage.updateView(size) leftLabel.updateView(size) rightLabel.updateView(size) @@ -48,48 +33,23 @@ import UIKit guard leftImage.superview == nil else { return } - containerView.translatesAutoresizingMaskIntoConstraints = false - contentView.heightAnchor.constraint(equalToConstant: cellHeight).isActive = true - contentView.addSubview(containerView) - - //containerView constraints - containerView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true - containerView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true - containerView.topAnchor.constraint(equalTo: topAnchor).isActive = true - containerView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true - - containerView.addSubview(leftImage) - containerView.addSubview(leftLabel) - containerView.addSubview(rightLabel) - - //leftImage constraints - leftImage.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: horizontalPadding).isActive = true - leftImage.centerYAnchor.constraint(equalTo: leftLabel.centerYAnchor).isActive = true - leftImage.widthAnchor.constraint(equalToConstant: imageSize).isActive = true - leftImage.heightAnchor.constraint(equalToConstant: imageSize).isActive = true - - - //leftLabel constraints - leftLabel.leadingAnchor.constraint(equalTo: leftImage.trailingAnchor, constant: spaceBetweenImageAndLeftLabel).isActive = true - leftLabel.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true - leftLabel.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true - - //rightLabel constraints - rightLabel.leadingAnchor.constraint(greaterThanOrEqualTo: leftLabel.trailingAnchor, constant: spaceBetweenLabels).isActive = true - rightLabel.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true - rightLabel.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true - rightLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor,constant: -horizontalPadding - 20).isActive = true + stack.translatesAutoresizingMaskIntoConstraints = false + stack.stackItems = [StackItem(andContain: leftImage),StackItem(andContain: leftLabel),StackItem(andContain: rightLabel)] + contentView.addSubview(stack) + containerHelper.constrainView(stack) + leftLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 901), for: .horizontal) + rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 902), for: .horizontal) + } - //---------------------------------------------------- // MARK: - Molecule //------------------------------------------------------ - override open func reset() { super.reset() leftImage.reset() leftLabel.reset() rightLabel.reset() + stack.reset() } public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { @@ -98,5 +58,17 @@ import UIKit leftImage.setWithModel(model.image, delegateObject, additionalData) leftLabel.setWithModel(model.leftLabel, delegateObject, additionalData) rightLabel.setWithModel(model.rightLabel, delegateObject, additionalData) + + // Create a stack model to use for the internal stack and set the alignment of labels + let leftImage = StackItemModel() + leftImage.horizontalAlignment = .fill + let leftLabel = StackItemModel() + leftLabel.horizontalAlignment = .fill + let rightLabel = StackItemModel() + rightLabel.horizontalAlignment = .trailing + let stackModel = StackModel(molecules: [leftImage,leftLabel,rightLabel]) + stackModel.axis = .horizontal + stack.model = stackModel + stack.restack() } } diff --git a/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaretModel.swift b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaretModel.swift index b29affb8..1ad7afbc 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaretModel.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaretModel.swift @@ -11,6 +11,7 @@ import Foundation public class ListLeftVariableIconWithRightCaretModel: ContainerModel, ListItemModelProtocol { public var line: LineModel? + public var style: String? = "standard" public var hideArrow: Bool? = false public var backgroundColor: Color? public var action: ActionModelProtocol? @@ -26,11 +27,8 @@ public class ListLeftVariableIconWithRightCaretModel: ContainerModel, ListItemMo if useVerticalMargins == nil { useVerticalMargins = true } - if topMarginPadding == nil { - topMarginPadding = 24 - } - if bottomMarginPadding == nil { - bottomMarginPadding = 0 + if image.height == nil { + image.height = 30.0 } } From 692689a90056914342d652b69ed4d6d25c80e758 Mon Sep 17 00:00:00 2001 From: Subhankar Acharya Date: Thu, 13 Feb 2020 00:34:41 +0530 Subject: [PATCH 32/57] Code clean up for stack and removed line break. --- .../ListLeftVariableIconWithRightCaret.swift | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift index 9cdf9cee..9fd26d4a 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift @@ -23,9 +23,7 @@ import UIKit //------------------------------------------------------- open override func updateView(_ size: CGFloat) { super.updateView(size) - leftImage.updateView(size) - leftLabel.updateView(size) - rightLabel.updateView(size) + stack.updateView(size) } override open func setupView() { @@ -39,16 +37,12 @@ import UIKit containerHelper.constrainView(stack) leftLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 901), for: .horizontal) rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 902), for: .horizontal) - } //---------------------------------------------------- // MARK: - Molecule //------------------------------------------------------ override open func reset() { super.reset() - leftImage.reset() - leftLabel.reset() - rightLabel.reset() stack.reset() } From 05bda7076de3334ff73532509a74e4dfe431b4b2 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 12 Feb 2020 14:39:38 -0500 Subject: [PATCH 33/57] Layout constraint helpers --- MVMCoreUI.xcodeproj/project.pbxproj | 2 +- .../Items => BaseClasses}/TableViewCell.swift | 13 +++- .../NSLayoutConstraintExtension.swift | 74 +++++++++++-------- .../ImageHeadlineBody.swift | 19 +---- .../Molecules/Items/StackItemModel.swift | 2 +- .../HeadlineBodyLinkToggle.swift | 2 +- .../ToggleMolecules/HeadlineBodyToggle.swift | 2 +- .../ToggleMolecules/LabelToggle.swift | 2 +- 8 files changed, 64 insertions(+), 52 deletions(-) rename MVMCoreUI/{Molecules/Items => BaseClasses}/TableViewCell.swift (97%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 8812759f..c8e5f8d8 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -919,7 +919,6 @@ D22479912316A9EF003FCCF9 /* Items */ = { isa = PBXGroup; children = ( - D2755D7A23689C7500485468 /* TableViewCell.swift */, 01EB368923609801006832FA /* ListItemModel.swift */, 01509D8E2327EC6F00EF99AA /* MoleculeTableViewCell.swift */, 012A88C1238D7BCA00FE3DA1 /* CarouselItemModel.swift */, @@ -1378,6 +1377,7 @@ D2B18B7E2360913400A9AEDC /* Control.swift */, D2B18B802360945C00A9AEDC /* View.swift */, 0AE14F63238315D2005417F8 /* TextField.swift */, + D2755D7A23689C7500485468 /* TableViewCell.swift */, 0A5D59C323AD488600EFD9E9 /* Protocols */, ); path = BaseClasses; diff --git a/MVMCoreUI/Molecules/Items/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift similarity index 97% rename from MVMCoreUI/Molecules/Items/TableViewCell.swift rename to MVMCoreUI/BaseClasses/TableViewCell.swift index cd8a3cdf..81b61d34 100644 --- a/MVMCoreUI/Molecules/Items/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -28,6 +28,8 @@ import UIKit private var heroAccessoryCenter: CGPoint? + private var initialSetupPerformed = false + // MARK: - Styling open func style(with styleString: String?) { guard let styleString = styleString else { @@ -102,12 +104,19 @@ import UIKit // MARK: - Inits public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) - setupView() + initialSetup() } public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) - setupView() + initialSetup() + } + + public func initialSetup() { + if !initialSetupPerformed { + initialSetupPerformed = true + setupView() + } } // MARK: - MFViewProtocol diff --git a/MVMCoreUI/Categories/NSLayoutConstraintExtension.swift b/MVMCoreUI/Categories/NSLayoutConstraintExtension.swift index bf6c8f65..4057a88c 100644 --- a/MVMCoreUI/Categories/NSLayoutConstraintExtension.swift +++ b/MVMCoreUI/Categories/NSLayoutConstraintExtension.swift @@ -9,36 +9,52 @@ import Foundation public extension NSLayoutConstraint { - static func pinSubviewsCenter(leftView: UIView, rightView: UIView) { - guard let superView = leftView.superview else { - return + + /// Pins the views vertically in the super view, allowing the super to expand depending on the tallest view. Shorter views are aligned center. + static func pinViewsVerticalExpandableAlignCenter(_ views: [UIView]) { + for view in views { + guard let superView = view.superview else { + return + } + view.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true + view.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true + superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true + + var constraint = view.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor) + constraint.priority = .defaultLow + constraint.isActive = true + + constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor) + constraint.priority = .defaultLow + constraint.isActive = true } - leftView.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true - leftView.leftAnchor.constraint(equalTo: superView.layoutMarginsGuide.leftAnchor).isActive = true - leftView.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true - superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: leftView.bottomAnchor).isActive = true + } + + /// Pins the views vertically in the super view, allowing the super to expand depending on the tallest view. Shorter views are aligned top. + static func pinViewsVerticalExpandableAlignTop(_ views: [UIView]) { + for view in views { + guard let superView = view.superview else { + return + } + view.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor).isActive = true + superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true - var constraint = leftView.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor) - constraint.priority = .defaultLow - constraint.isActive = true - - constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: leftView.bottomAnchor) - constraint.priority = .defaultLow - constraint.isActive = true - - rightView.leftAnchor.constraint(greaterThanOrEqualTo: leftView.rightAnchor, constant: 16).isActive = true - - rightView.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true - superView.layoutMarginsGuide.rightAnchor.constraint(equalTo: rightView.rightAnchor).isActive = true - rightView.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true - superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: rightView.bottomAnchor).isActive = true - - constraint = rightView.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor) - constraint.priority = .defaultLow - constraint.isActive = true - - constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: rightView.bottomAnchor) - constraint.priority = .defaultLow - constraint.isActive = true + let constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor) + constraint.priority = .defaultLow + constraint.isActive = true + } + } + + /// Pins a view to the left and a view to the right, flexible space in between. The super can expand depending on the taller view. Shorter views are aligned top if alignTop true, else aligned center. + static func pinViews(leftView: UIView, rightView: UIView, alignTop: Bool) { + guard let superView = leftView.superview else { return } + if alignTop { + pinViewsVerticalExpandableAlignTop([leftView, rightView]) + } else { + pinViewsVerticalExpandableAlignCenter([leftView, rightView]) + } + leftView.leadingAnchor.constraint(equalTo: superView.layoutMarginsGuide.leadingAnchor).isActive = true + superView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightView.trailingAnchor).isActive = true + rightView.leftAnchor.constraint(greaterThanOrEqualTo: leftView.rightAnchor, constant: PaddingHorizontalBetweenRelatedItems).isActive = true } } diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/ImageHeadlineBody.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/ImageHeadlineBody.swift index 089352c7..840f4763 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/ImageHeadlineBody.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/ImageHeadlineBody.swift @@ -10,13 +10,14 @@ import UIKit @objcMembers open class ImageHeadlineBody: View { let headlineBody = HeadlineBody(frame: .zero) - let imageView = MFLoadImageView() + let imageView = MFLoadImageView(pinnedEdges: .all) var constraintBetweenImageLabelsConstant: CGFloat = 16 var constraintBetweenImageLabels: NSLayoutConstraint? // MARK: - MFViewProtocol open override func setupView() { + super.setupView() guard subviews.count == 0 else { return } @@ -26,23 +27,9 @@ import UIKit addSubview(headlineBody) addSubview(imageView) - headlineBody.topAnchor.constraint(equalTo: topAnchor).isActive = true + NSLayoutConstraint.pinViewsVerticalExpandableAlignCenter([imageView, headlineBody]) rightAnchor.constraint(equalTo: headlineBody.rightAnchor).isActive = true - bottomAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor).isActive = true - var constraint = bottomAnchor.constraint(equalTo: headlineBody.bottomAnchor) - constraint.priority = .defaultLow - constraint.isActive = true - - imageView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true imageView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true - imageView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor).isActive = true - bottomAnchor.constraint(greaterThanOrEqualTo: imageView.bottomAnchor).isActive = true - constraint = bottomAnchor.constraint(equalTo: imageView.bottomAnchor) - constraint.priority = UILayoutPriority(rawValue: 200) - constraint.isActive = true - constraint = imageView.topAnchor.constraint(equalTo: topAnchor) - constraint.priority = UILayoutPriority(rawValue: 200) - constraint.isActive = true constraintBetweenImageLabels = headlineBody.leadingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: constraintBetweenImageLabelsConstant) constraintBetweenImageLabels?.isActive = true diff --git a/MVMCoreUI/Molecules/Items/StackItemModel.swift b/MVMCoreUI/Molecules/Items/StackItemModel.swift index f296986e..9d193f17 100644 --- a/MVMCoreUI/Molecules/Items/StackItemModel.swift +++ b/MVMCoreUI/Molecules/Items/StackItemModel.swift @@ -8,7 +8,7 @@ import Foundation -@objcMembers public class StackItemModel: StackItemModelProtocol, MoleculeModelProtocol { +@objcMembers public class StackItemModel: ContainerModel, StackItemModelProtocol, MoleculeModelProtocol { public static var identifier: String = "simpleStackItem" public var backgroundColor: Color? public var spacing: CGFloat? diff --git a/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggle.swift b/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggle.swift index 7359ed3c..07639dbe 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggle.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggle.swift @@ -27,7 +27,7 @@ import UIKit headlineBodyLink.headlineBody.styleListItem() addSubview(headlineBodyLink) addSubview(toggle) - NSLayoutConstraint.pinSubviewsCenter(leftView: headlineBodyLink, rightView: toggle) + NSLayoutConstraint.pinViews(leftView: headlineBodyLink, rightView: toggle, alignTop: false) } // MARK: - MVMCoreUIMoleculeViewProtoco diff --git a/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggle.swift b/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggle.swift index 324d63da..8df94fa8 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggle.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggle.swift @@ -31,7 +31,7 @@ import UIKit view.addSubview(headlineBody) view.addSubview(toggle) - NSLayoutConstraint.pinSubviewsCenter(leftView: headlineBody, rightView: toggle) + NSLayoutConstraint.pinViews(leftView: headlineBody, rightView: toggle, alignTop: false) } // MARK:- ModelMoleculeViewProtocol diff --git a/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift b/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift index 3d00b820..f2925cc9 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ToggleMolecules/LabelToggle.swift @@ -28,7 +28,7 @@ import UIKit addSubview(label) addSubview(toggle) label.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical) - NSLayoutConstraint.pinSubviewsCenter(leftView: label, rightView: toggle) + NSLayoutConstraint.pinViews(leftView: label, rightView: toggle, alignTop: false) } // MARK:- ModelMoleculeViewProtocol From 0113387f008ae0815e407661db8fd69c37fe62c8 Mon Sep 17 00:00:00 2001 From: "Xinlei(Ryan) Pan" Date: Wed, 12 Feb 2020 15:31:45 -0500 Subject: [PATCH 34/57] add new image method --- MVMCoreUI/Atoms/Views/Label/Label.swift | 2 +- MVMCoreUI/Atoms/Views/MFLoadImageView.swift | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atoms/Views/Label/Label.swift index 576f66b9..9a4d4612 100644 --- a/MVMCoreUI/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label/Label.swift @@ -752,7 +752,7 @@ extension Label { /// Applied to existing text. Removes underlines of tappable links and assoated actionable clauses. @objc public func clearActionableClauses() { - + MVMCoreUICommonViewsUtility.commonView() guard let attributedText = attributedText else { return } let mutableAttributedString = NSMutableAttributedString(attributedString: attributedText) diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift index 242e299a..1c54b891 100644 --- a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift @@ -357,6 +357,10 @@ import UIKit loadImage(withName: imageName, format: nil, width: width, height: height, customFallbackImage: nil, completionHandler: completionHandler) } + public func loadImage(withName imageName: String?, width: NSNumber?, height: NSNumber?, customFallbackImage: String?, completionHandler: @escaping MVMCoreGetImageBlock) { + loadImage(withName: imageName, format: nil, width: width, height: height, customFallbackImage: customFallbackImage, completionHandler: completionHandler) + } + public func loadImage(withName imageName: String?, format: String?, width: NSNumber?, height: NSNumber?, customFallbackImage: String?) { loadImage(withName: imageName, format: format, width: width, height: height, customFallbackImage: customFallbackImage, completionHandler: defaultCompletionBlock()) } From e1d56bcc0cbe7a16a22cbb79327b9e6ae26ddf4e Mon Sep 17 00:00:00 2001 From: "Xinlei(Ryan) Pan" Date: Wed, 12 Feb 2020 15:32:33 -0500 Subject: [PATCH 35/57] update image method --- MVMCoreUI/Atoms/Views/Label/Label.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/MVMCoreUI/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atoms/Views/Label/Label.swift index 9a4d4612..013f7f11 100644 --- a/MVMCoreUI/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label/Label.swift @@ -752,7 +752,6 @@ extension Label { /// Applied to existing text. Removes underlines of tappable links and assoated actionable clauses. @objc public func clearActionableClauses() { - MVMCoreUICommonViewsUtility.commonView() guard let attributedText = attributedText else { return } let mutableAttributedString = NSMutableAttributedString(attributedString: attributedText) From 5cecd5f031d02d5b4d546b89dd57020220138ec2 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 12 Feb 2020 20:36:05 -0500 Subject: [PATCH 36/57] Minor fixes --- MVMCoreUI.xcodeproj/project.pbxproj | 4 ++-- .../ListLeftVariableIconWithRightCaret.swift | 8 +++++++- .../ListLeftVariableIconWithRightCaretModel.swift | 6 +++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index e02f3542..efe433b4 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -896,9 +896,9 @@ D224798F2316A99F003FCCF9 /* LeftRightViews */ = { isa = PBXGroup; children = ( - D2E2A99723D8D63C000B42E6 /* ActionDetailWithImageModel.swift */, - 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */, 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */, + 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */, + D2E2A99723D8D63C000B42E6 /* ActionDetailWithImageModel.swift */, 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */, D28A839023CD4FD400DFE4FC /* CornerLabelsModel.swift */, 01509D902327ECE600EF99AA /* CornerLabels.swift */, diff --git a/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift index 9fd26d4a..62a19d01 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaret.swift @@ -14,10 +14,11 @@ import UIKit //----------------------------------------------------- // MARK: - Outlets //------------------------------------------------------- - let leftImage = MFLoadImageView() + let leftImage = MFLoadImageView(pinnedEdges: .all) let leftLabel = Label.commonLabelB2(true) let rightLabel = Label.commonLabelB2(true) let stack = Stack(frame: .zero) + //----------------------------------------------------- // MARK: - View Lifecycle //------------------------------------------------------- @@ -38,6 +39,7 @@ import UIKit leftLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 901), for: .horizontal) rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 902), for: .horizontal) } + //---------------------------------------------------- // MARK: - Molecule //------------------------------------------------------ @@ -65,4 +67,8 @@ import UIKit stack.model = stackModel stack.restack() } + + public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 90 + } } diff --git a/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaretModel.swift b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaretModel.swift index 1ad7afbc..cac928d3 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaretModel.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/ListLeftVariableIconWithRightCaretModel.swift @@ -37,6 +37,7 @@ public class ListLeftVariableIconWithRightCaretModel: ContainerModel, ListItemMo self.leftLabel = leftLabel self.rightLabel = rightLabel super.init() + setDefaults() } private enum CodingKeys: String, CodingKey { @@ -45,6 +46,7 @@ public class ListLeftVariableIconWithRightCaretModel: ContainerModel, ListItemMo case rightLabel case image case action + case backgroundColor } required public init(from decoder: Decoder) throws { @@ -53,6 +55,7 @@ public class ListLeftVariableIconWithRightCaretModel: ContainerModel, ListItemMo rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) image = try typeContainer.decode(ImageViewModel.self, forKey: .image) action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) try super.init(from: decoder) setDefaults() } @@ -60,10 +63,11 @@ public class ListLeftVariableIconWithRightCaretModel: ContainerModel, ListItemMo public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(ListLeftVariableIconWithRightCaretModel.identifier, forKey: .moleculeName) + try container.encode(moleculeName, forKey: .moleculeName) try container.encode(leftLabel, forKey: .leftLabel) try container.encode(rightLabel, forKey: .rightLabel) try container.encode(image, forKey: .image) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeModelIfPresent(action, forKey: .action) } } From 5b898b1b215d629a2c2bd3ebcb66f5fc18de9eb1 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 12 Feb 2020 20:56:05 -0500 Subject: [PATCH 37/57] small clean and reorg --- MVMCoreUI.xcodeproj/project.pbxproj | 48 ++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index c5ec4836..b1e42d4b 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -888,8 +888,6 @@ D224798E2316A995003FCCF9 /* HorizontalCombinationViews */ = { isa = PBXGroup; children = ( - 5248BFEA23F12E350059236A /* ListThreeColumnPlanDataDivider.swift */, - 5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */, D2E2A99B23D8D975000B42E6 /* ImageHeadlineBodyModel.swift */, D2B1E3E422F37D6A0065F95C /* ImageHeadlineBody.swift */, D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */, @@ -902,8 +900,6 @@ D224798F2316A99F003FCCF9 /* LeftRightViews */ = { isa = PBXGroup; children = ( - 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */, - 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */, D2E2A99723D8D63C000B42E6 /* ActionDetailWithImageModel.swift */, 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */, D28A839023CD4FD400DFE4FC /* CornerLabelsModel.swift */, @@ -950,6 +946,49 @@ path = Items; sourceTree = ""; }; + D22B38E923F4E07800490EF6 /* DesignedComponents */ = { + isa = PBXGroup; + children = ( + D22B38EC23F4E10700490EF6 /* SectionDividers */, + D22B38EA23F4E08B00490EF6 /* List */, + ); + path = DesignedComponents; + sourceTree = ""; + }; + D22B38EA23F4E08B00490EF6 /* List */ = { + isa = PBXGroup; + children = ( + D22B38EB23F4E0AE00490EF6 /* LeftVariable */, + ); + path = List; + sourceTree = ""; + }; + D22B38EB23F4E0AE00490EF6 /* LeftVariable */ = { + isa = PBXGroup; + children = ( + 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */, + 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */, + ); + path = LeftVariable; + sourceTree = ""; + }; + D22B38EC23F4E10700490EF6 /* SectionDividers */ = { + isa = PBXGroup; + children = ( + D22B38ED23F4E11100490EF6 /* ThreeColumn */, + ); + path = SectionDividers; + sourceTree = ""; + }; + D22B38ED23F4E11100490EF6 /* ThreeColumn */ = { + isa = PBXGroup; + children = ( + 5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */, + 5248BFEA23F12E350059236A /* ListThreeColumnPlanDataDivider.swift */, + ); + path = ThreeColumn; + sourceTree = ""; + }; D22D1F582204D2590077CEC0 /* Legacy */ = { isa = PBXGroup; children = ( @@ -1052,6 +1091,7 @@ D29DF10E21E67A77003B2FB9 /* Molecules */ = { isa = PBXGroup; children = ( + D22B38E923F4E07800490EF6 /* DesignedComponents */, D22479912316A9EF003FCCF9 /* Items */, D224798F2316A99F003FCCF9 /* LeftRightViews */, D224798E2316A995003FCCF9 /* HorizontalCombinationViews */, From 54e012d69908b0968a691ff064305a3814f9961c Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 12 Feb 2020 21:55:27 -0500 Subject: [PATCH 38/57] name fix --- MVMCoreUI/BaseControllers/MFViewController+Model.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/BaseControllers/MFViewController+Model.swift b/MVMCoreUI/BaseControllers/MFViewController+Model.swift index 1c58c574..1ddbd4ab 100644 --- a/MVMCoreUI/BaseControllers/MFViewController+Model.swift +++ b/MVMCoreUI/BaseControllers/MFViewController+Model.swift @@ -16,8 +16,8 @@ extension MFViewController: MoleculeDelegateProtocol { return loadObject?.modulesJSON?.optionalDictionaryForKey(name) } - public func getModuleWithName(_ moduleName: String) -> MoleculeModelProtocol? { - guard let moduleJSON = loadObject?.modulesJSON?.optionalDictionaryForKey(moduleName), + public func getModuleWithName(_ moleculeName: String) -> MoleculeModelProtocol? { + guard let moduleJSON = loadObject?.modulesJSON?.optionalDictionaryForKey(moleculeName), let moleculeName = moduleJSON.optionalStringForKey("moleculeName"), let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self) else { return nil } From 24f44e58292df1efef48ff2654468380cc24a0b6 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 12 Feb 2020 22:03:46 -0500 Subject: [PATCH 39/57] Small cleaning --- .../ListItemModelProtocol.swift | 12 ------------ .../MoleculeModelProtocol.swift | 3 --- .../ModelProtocols/PageModelProtocol.swift | 19 +------------------ .../TemplateModelProtocol.swift | 10 +++++++++- 4 files changed, 10 insertions(+), 34 deletions(-) diff --git a/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift index cd19a23c..020c3cbe 100644 --- a/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift @@ -28,16 +28,4 @@ public extension ListItemModelProtocol { get { return nil } set { } } - - var moleculeName: String? { - get { return Self.identifier } - } - - var categoryName: String { - return "\(ListItemModelProtocol.self)" - } - -// var categoryCodingKey: String { -// return "style" -// } } diff --git a/MVMCoreUI/Models/ModelProtocols/MoleculeModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/MoleculeModelProtocol.swift index 9f099331..1ec0d13c 100644 --- a/MVMCoreUI/Models/ModelProtocols/MoleculeModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/MoleculeModelProtocol.swift @@ -4,9 +4,6 @@ import Foundation public protocol MoleculeModelProtocol: Model { var moleculeName: String? { get } var backgroundColor: Color? { get set} - - static var categoryName: String { get } - static var categoryCodingKey: String { get } } public extension MoleculeModelProtocol { diff --git a/MVMCoreUI/Models/ModelProtocols/PageModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/PageModelProtocol.swift index 2ad9b8a2..34b58818 100644 --- a/MVMCoreUI/Models/ModelProtocols/PageModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/PageModelProtocol.swift @@ -9,25 +9,8 @@ import Foundation -public protocol PageModelProtocol: Model { +public protocol PageModelProtocol { var pageType: String { get set } var screenHeading: String? { get set } var isAtomicTabs: Bool? { get set } - - static var categoryName: String { get } - static var categoryCodingKey: String { get } -} - -extension PageModelProtocol { - //TODO: Scott implement - - public static var categoryCodingKey: String { - return "moleculeName" - } - - public static var categoryName: String { - return "\(PageModelProtocol.self)" - } -// public static var categoryName: String { return "template" } -// public static var categoryCodingKey: String { return "\(PageModelProtocol.self)" } } diff --git a/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift index 90a8ec2a..793baa0a 100644 --- a/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift @@ -9,7 +9,7 @@ import Foundation -public protocol TemplateModelProtocol: PageModelProtocol { +public protocol TemplateModelProtocol: PageModelProtocol, Model { var template: String { get } } @@ -18,4 +18,12 @@ public extension TemplateModelProtocol { var template: String { get { return Self.identifier } } + + static var categoryCodingKey: String { + return "template" + } + + static var categoryName: String { + return "\(TemplateModelProtocol.self)" + } } From 66a06d98159e1e64251b5b682c007c8d212f79f6 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 13 Feb 2020 10:19:22 -0500 Subject: [PATCH 40/57] Clean up and list item convenience --- MVMCoreUI.xcodeproj/project.pbxproj | 14 ++++--- .../ListLeftVariableIconWithRightCaret.swift | 3 -- ...tLeftVariableIconWithRightCaretModel.swift | 25 ++--------- .../ListThreeColumnPlanDataDivider.swift | 4 +- .../ListThreeColumnPlanDataDividerModel.swift | 20 ++------- .../Items/AccordionListItemModel.swift | 26 ++++++------ .../AccordionMoleculeTableViewCell.swift | 10 ++++- .../Items/DropDownFilterTableViewCell.swift | 4 +- .../Items/DropDownListItemModel.swift | 41 ++++--------------- MVMCoreUI/Molecules/Items/ListItemModel.swift | 33 ++++++--------- .../Items/MoleculeListItemModel.swift | 41 +++++++++++++++++++ .../Items/MoleculeTableViewCell.swift | 4 +- .../Molecules/Items/TabsListItemModel.swift | 31 ++++++-------- .../Molecules/Items/TabsTableViewCell.swift | 22 ++++++---- .../ModelMoleculeDelegateProtocol.swift | 8 ++-- .../OtherHandlers/MoleculeObjectMapping.swift | 2 +- .../Templates/ListPageTemplateModel.swift | 6 +-- .../Templates/MoleculeListTemplate.swift | 21 +++++----- 18 files changed, 149 insertions(+), 166 deletions(-) create mode 100644 MVMCoreUI/Molecules/Items/MoleculeListItemModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index ad2719bb..d114d2ae 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -54,7 +54,7 @@ 01E569D3223FFFA500327251 /* ThreeLayerViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */; }; 01EB368F23609801006832FA /* LabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368823609801006832FA /* LabelModel.swift */; }; - 01EB369023609801006832FA /* ListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368923609801006832FA /* ListItemModel.swift */; }; + 01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368923609801006832FA /* MoleculeListItemModel.swift */; }; 01EB369223609801006832FA /* MoleculeStackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368B23609801006832FA /* MoleculeStackModel.swift */; }; 01EB369323609801006832FA /* HeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368C23609801006832FA /* HeaderModel.swift */; }; 01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368D23609801006832FA /* HeadlineBodyModel.swift */; }; @@ -169,6 +169,7 @@ D260D7B622D68514007E7233 /* MVMCoreUIPagingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368A23609801006832FA /* MoleculeStackItemModel.swift */; }; D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */; }; + D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */; }; D274CA332236A78900B01B62 /* FooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D274CA322236A78900B01B62 /* FooterView.swift */; }; D2755D7B23689C7500485468 /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2755D7A23689C7500485468 /* TableViewCell.swift */; }; D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */; }; @@ -384,7 +385,7 @@ 01C851D223CF9E740021F976 /* LabelToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelToggleModel.swift; sourceTree = ""; }; 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeModelProtocol.swift; sourceTree = ""; }; 01EB368823609801006832FA /* LabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelModel.swift; sourceTree = ""; }; - 01EB368923609801006832FA /* ListItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListItemModel.swift; sourceTree = ""; }; + 01EB368923609801006832FA /* MoleculeListItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeListItemModel.swift; sourceTree = ""; }; 01EB368A23609801006832FA /* MoleculeStackItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackItemModel.swift; sourceTree = ""; }; 01EB368B23609801006832FA /* MoleculeStackModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackModel.swift; sourceTree = ""; }; 01EB368C23609801006832FA /* HeaderModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderModel.swift; sourceTree = ""; }; @@ -489,6 +490,7 @@ D260D7B022D65BDD007E7233 /* MVMCoreUIPageControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIPageControl.m; sourceTree = ""; }; D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIPagingProtocol.h; sourceTree = ""; }; D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropDownFilterTableViewCell.swift; sourceTree = ""; }; + D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemModel.swift; sourceTree = ""; }; D274CA322236A78900B01B62 /* FooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FooterView.swift; sourceTree = ""; }; D2755D7A23689C7500485468 /* TableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewCell.swift; sourceTree = ""; }; D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsTableViewCell.swift; sourceTree = ""; }; @@ -927,8 +929,8 @@ D22479912316A9EF003FCCF9 /* Items */ = { isa = PBXGroup; children = ( - D2755D7A23689C7500485468 /* TableViewCell.swift */, - 01EB368923609801006832FA /* ListItemModel.swift */, + D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */, + 01EB368923609801006832FA /* MoleculeListItemModel.swift */, 01509D8E2327EC6F00EF99AA /* MoleculeTableViewCell.swift */, 012A88C1238D7BCA00FE3DA1 /* CarouselItemModel.swift */, D2A6390422CBCE160052ED1F /* MoleculeCollectionViewCell.swift */, @@ -1430,6 +1432,7 @@ D2B18B7E2360913400A9AEDC /* Control.swift */, D2B18B802360945C00A9AEDC /* View.swift */, 0AE14F63238315D2005417F8 /* TextField.swift */, + D2755D7A23689C7500485468 /* TableViewCell.swift */, 0A5D59C323AD488600EFD9E9 /* Protocols */, ); path = BaseClasses; @@ -1682,7 +1685,7 @@ 012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */, D2A514672213885800345BFB /* HeaderView.swift in Sources */, D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */, - 01EB369023609801006832FA /* ListItemModel.swift in Sources */, + 01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */, D28A838323CCBD3F00DFE4FC /* CircleProgressModel.swift in Sources */, D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */, DBEFFA04225A829700230692 /* Label.swift in Sources */, @@ -1792,6 +1795,7 @@ D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */, D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */, 0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */, + D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */, 0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */, 94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */, 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */, diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift index 62a19d01..9f0e2deb 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift @@ -29,9 +29,6 @@ import UIKit override open func setupView() { super.setupView() - guard leftImage.superview == nil else { - return - } stack.translatesAutoresizingMaskIntoConstraints = false stack.stackItems = [StackItem(andContain: leftImage),StackItem(andContain: leftLabel),StackItem(andContain: rightLabel)] contentView.addSubview(stack) diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretModel.swift b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretModel.swift index cac928d3..bccf5320 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretModel.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretModel.swift @@ -8,25 +8,14 @@ import Foundation -public class ListLeftVariableIconWithRightCaretModel: ContainerModel, ListItemModelProtocol { - - public var line: LineModel? - public var style: String? = "standard" - public var hideArrow: Bool? = false - public var backgroundColor: Color? - public var action: ActionModelProtocol? +public class ListLeftVariableIconWithRightCaretModel: ListItemModel, MoleculeModelProtocol { public static var identifier: String = "listLVImg" public var image: ImageViewModel public var leftLabel: LabelModel public var rightLabel: LabelModel - func setDefaults() { - if useHorizontalMargins == nil { - useHorizontalMargins = true - } - if useVerticalMargins == nil { - useVerticalMargins = true - } + override public func setDefaults() { + super.setDefaults() if image.height == nil { image.height = 30.0 } @@ -37,7 +26,6 @@ public class ListLeftVariableIconWithRightCaretModel: ContainerModel, ListItemMo self.leftLabel = leftLabel self.rightLabel = rightLabel super.init() - setDefaults() } private enum CodingKeys: String, CodingKey { @@ -45,8 +33,6 @@ public class ListLeftVariableIconWithRightCaretModel: ContainerModel, ListItemMo case leftLabel case rightLabel case image - case action - case backgroundColor } required public init(from decoder: Decoder) throws { @@ -54,10 +40,7 @@ public class ListLeftVariableIconWithRightCaretModel: ContainerModel, ListItemMo leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel) rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) image = try typeContainer.decode(ImageViewModel.self, forKey: .image) - action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType) - backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) try super.init(from: decoder) - setDefaults() } public override func encode(to encoder: Encoder) throws { @@ -67,8 +50,6 @@ public class ListLeftVariableIconWithRightCaretModel: ContainerModel, ListItemMo try container.encode(leftLabel, forKey: .leftLabel) try container.encode(rightLabel, forKey: .rightLabel) try container.encode(image, forKey: .image) - try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) - try container.encodeModelIfPresent(action, forKey: .action) } } diff --git a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift index e685ce6b..19774110 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift @@ -23,9 +23,7 @@ import Foundation open override func setupView() { super.setupView() - guard leftHeadlineBody.superview == nil else { - return - } + //using stackItems to align the three headlineBody stack.translatesAutoresizingMaskIntoConstraints = false stack.stackItems = [StackItem(andContain: leftHeadlineBody),StackItem(andContain: centerHeadLineBody),StackItem(andContain: rightHeadLineBody)] diff --git a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDividerModel.swift b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDividerModel.swift index 47e97a5a..fd946eb0 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDividerModel.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDividerModel.swift @@ -8,11 +8,7 @@ import UIKit -public class ListThreeColumnPlanDataDividerModel: ContainerModel, ListItemModelProtocol { - public var hideArrow: Bool? - public var style: String? = "tallDivider" - public var line: LineModel? - public var backgroundColor: Color? +public class ListThreeColumnPlanDataDividerModel: ListItemModel, MoleculeModelProtocol { public static var identifier: String = "list3CHBDiv" public var leftHeadlineBody: HeadlineBodyModel public var centerHeadlineBody: HeadlineBodyModel @@ -27,13 +23,9 @@ public class ListThreeColumnPlanDataDividerModel: ContainerModel, ListItemModelP } /// Defaults to set - func setDefaults() { - if useHorizontalMargins == nil { - useHorizontalMargins = true - } - if useVerticalMargins == nil { - useVerticalMargins = true - } + override public func setDefaults() { + super.setDefaults() + style = "tallDivider" } private enum CodingKeys: String, CodingKey { @@ -41,7 +33,6 @@ public class ListThreeColumnPlanDataDividerModel: ContainerModel, ListItemModelP case leftHeadlineBody case centerHeadlineBody case rightHeadlineBody - case backgroundColor } required public init(from decoder: Decoder) throws { @@ -49,9 +40,7 @@ public class ListThreeColumnPlanDataDividerModel: ContainerModel, ListItemModelP leftHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .leftHeadlineBody) centerHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .centerHeadlineBody) rightHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .rightHeadlineBody) - backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) try super.init(from: decoder) - setDefaults() } public override func encode(to encoder: Encoder) throws { @@ -61,7 +50,6 @@ public class ListThreeColumnPlanDataDividerModel: ContainerModel, ListItemModelP try container.encode(leftHeadlineBody, forKey: .leftHeadlineBody) try container.encode(centerHeadlineBody, forKey: .centerHeadlineBody) try container.encode(rightHeadlineBody, forKey: .rightHeadlineBody) - try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) } } diff --git a/MVMCoreUI/Molecules/Items/AccordionListItemModel.swift b/MVMCoreUI/Molecules/Items/AccordionListItemModel.swift index 0e2fa531..788ef919 100644 --- a/MVMCoreUI/Molecules/Items/AccordionListItemModel.swift +++ b/MVMCoreUI/Molecules/Items/AccordionListItemModel.swift @@ -8,28 +8,28 @@ import UIKit -class AccordionListItemModel: MoleculeContainerModel, ListItemModelProtocol { - public static var identifier: String = "accordionListItem" - public var molecules: [ListItemModelProtocol] - public var backgroundColor: Color? +class AccordionListItemModel: MoleculeListItemModel { + override public class var identifier: String { + return "accordionListItem" + } + public var molecules: [ListItemModelProtocol & MoleculeModelProtocol] public var hideLineWhenExpanded: Bool = false - public var hideArrow: Bool? = true - public var line: LineModel? private enum CodingKeys: String, CodingKey { case moleculeName case molecules - case backgroundColor + case molecule case hideLineWhenExpanded - case hideArrow - case line + } + + public override func setDefaults() { + super.setDefaults() + hideArrow = true } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - molecules = try typeContainer.decodeMolecules(codingKey: .molecules) as! [ListItemModelProtocol] - backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) + molecules = try typeContainer.decodeMolecules(codingKey: .molecules) as! [ListItemModelProtocol & MoleculeModelProtocol] if let hideLine = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideLineWhenExpanded) { hideLineWhenExpanded = hideLine } @@ -41,8 +41,6 @@ class AccordionListItemModel: MoleculeContainerModel, ListItemModelProtocol { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeModels(molecules, forKey: .molecules) - try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(hideLineWhenExpanded, forKey: .hideLineWhenExpanded) - try container.encodeIfPresent(line, forKey: .line) } } diff --git a/MVMCoreUI/Molecules/Items/AccordionMoleculeTableViewCell.swift b/MVMCoreUI/Molecules/Items/AccordionMoleculeTableViewCell.swift index db4e322e..714c7dd9 100644 --- a/MVMCoreUI/Molecules/Items/AccordionMoleculeTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/AccordionMoleculeTableViewCell.swift @@ -9,7 +9,9 @@ import UIKit @objcMembers public class AccordionMoleculeTableViewCell: MoleculeTableViewCell { - var accordionListItemModel: AccordionListItemModel? + var accordionListItemModel: AccordionListItemModel? { + return listItemModel as? AccordionListItemModel + } let accordionButton = createAccordionButton() static func createAccordionButton() -> MFCustomButton { @@ -30,10 +32,14 @@ import UIKit override public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { accordionButton.isSelected = !accordionButton.isSelected accordionButton.setTitle(accordionButton.isSelected ? "-" : "+", for: .normal) - guard let molecules = accordionListItemModel?.molecules else { + guard let model = accordionListItemModel else { return } + guard let json = model.toJSON(), + let molecules = json.optionalArrayForKey("molecules") as? [[AnyHashable: Any]] + else { return } + if accordionButton.isSelected { delegateObject?.moleculeDelegate?.addMolecules(molecules, sender: self, animation: .automatic) } else { diff --git a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift index 081da875..164bd2c3 100644 --- a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift @@ -24,9 +24,7 @@ import UIKit override public func setupView() { super.setupView() - - guard dropDown.superview == nil else { return } - + addMolecule(dropDown) dropDown.observeDropdownChange = { [weak self] oldValue, newValue in diff --git a/MVMCoreUI/Molecules/Items/DropDownListItemModel.swift b/MVMCoreUI/Molecules/Items/DropDownListItemModel.swift index 35f69b51..b623f20e 100644 --- a/MVMCoreUI/Molecules/Items/DropDownListItemModel.swift +++ b/MVMCoreUI/Molecules/Items/DropDownListItemModel.swift @@ -8,43 +8,31 @@ import Foundation -@objcMembers public class DropDownListItemModel: ContainerModel, ListItemModelProtocol { +@objcMembers public class DropDownListItemModel: ListItemModel, MoleculeModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "dropDownListItem" - public var molecules: [[ListItemModelProtocol]] + public var molecules: [[ListItemModelProtocol & MoleculeModelProtocol]] public var dropDown: ItemDropdownEntryFieldModel - public var backgroundColor: Color? - public var line: LineModel? = LineModel(type: .none) - public var hideArrow: Bool? = true /// Defaults to set - func setDefaults() { - if useHorizontalMargins == nil { - useHorizontalMargins = true - } - if useVerticalMargins == nil { - useVerticalMargins = true - } - if topMarginPadding == nil { - topMarginPadding = 24 - } - if bottomMarginPadding == nil { - bottomMarginPadding = 0 - } + public override func setDefaults() { + super.setDefaults() + hideArrow = true + line = LineModel(type: .none) + style = "sectionFooter" } //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- - public init(molecules: [[ListItemModelProtocol]], dropDown: ItemDropdownEntryFieldModel) { + public init(molecules: [[ListItemModelProtocol & MoleculeModelProtocol]], dropDown: ItemDropdownEntryFieldModel) { self.molecules = molecules self.dropDown = dropDown super.init() - setDefaults() } //-------------------------------------------------- @@ -55,8 +43,6 @@ import Foundation case moleculeName case molecules case dropDown - case line - case backgroundColor } //-------------------------------------------------- @@ -65,16 +51,9 @@ import Foundation required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - molecules = try typeContainer.decodeMolecules2D(codingKey: .molecules) as? [[ListItemModelProtocol]] ?? [[]] + molecules = try typeContainer.decodeMolecules2D(codingKey: .molecules) as? [[ListItemModelProtocol & MoleculeModelProtocol]] ?? [[]] dropDown = try typeContainer.decode(ItemDropdownEntryFieldModel.self, forKey: .dropDown) - - if let lineModel = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) { - line = lineModel - } - - backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) try super.init(from: decoder) - setDefaults() } public override func encode(to encoder: Encoder) throws { @@ -83,7 +62,5 @@ import Foundation try container.encode(moleculeName, forKey: .moleculeName) try container.encodeModels2D(molecules, forKey: .molecules) try container.encode(dropDown, forKey: .dropDown) - try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) - try container.encodeIfPresent(line, forKey: .line) } } diff --git a/MVMCoreUI/Molecules/Items/ListItemModel.swift b/MVMCoreUI/Molecules/Items/ListItemModel.swift index ffb0eb35..973a487a 100644 --- a/MVMCoreUI/Molecules/Items/ListItemModel.swift +++ b/MVMCoreUI/Molecules/Items/ListItemModel.swift @@ -1,25 +1,22 @@ // -// ListItem.swift +// BaseListItemModel.swift // MVMCoreUI // -// Created by Suresh, Kamlesh on 10/3/19. -// Copyright © 2019 Suresh, Kamlesh. All rights reserved. +// Created by Scott Pfeil on 2/12/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. // +// A base class that has common list item boilerplate model stuffs. import Foundation -import MVMCore -@objcMembers public class ListItemModel: MoleculeContainerModel, ListItemModelProtocol { - - public static var identifier: String = "listItem" +@objcMembers public class ListItemModel: ContainerModel, ListItemModelProtocol { public var backgroundColor: Color? public var action: ActionModelProtocol? public var hideArrow: Bool? public var line: LineModel? - public var style: String? = "standard" + public var style: String? private enum CodingKeys: String, CodingKey { - case moleculeName case backgroundColor case action case hideArrow @@ -28,23 +25,20 @@ import MVMCore } /// Defaults to set - func setDefaults() { + public func setDefaults() { if useHorizontalMargins == nil { useHorizontalMargins = true } if useVerticalMargins == nil { useVerticalMargins = true } - if topMarginPadding == nil { - topMarginPadding = 24 - } - if bottomMarginPadding == nil { - bottomMarginPadding = 24 + if style == nil { + style = "standard" } } - public override init(with moleculeModel: MoleculeModelProtocol) { - super.init(with: moleculeModel) + public override init() { + super.init() setDefaults() } @@ -54,9 +48,7 @@ import MVMCore action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType) hideArrow = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideArrow) line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) - if let style = try typeContainer.decodeIfPresent(String.self, forKey: .style) { - self.style = style - } + style = try typeContainer.decodeIfPresent(String.self, forKey: .style) try super.init(from: decoder) setDefaults() } @@ -64,7 +56,6 @@ import MVMCore public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeModelIfPresent(action, forKey: .action) try container.encodeIfPresent(hideArrow, forKey: .hideArrow) diff --git a/MVMCoreUI/Molecules/Items/MoleculeListItemModel.swift b/MVMCoreUI/Molecules/Items/MoleculeListItemModel.swift new file mode 100644 index 00000000..499669c6 --- /dev/null +++ b/MVMCoreUI/Molecules/Items/MoleculeListItemModel.swift @@ -0,0 +1,41 @@ +// +// ListItem.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 10/3/19. +// Copyright © 2019 Suresh, Kamlesh. All rights reserved. +// + +import Foundation +import MVMCore + +@objcMembers public class MoleculeListItemModel: ListItemModel, MoleculeModelProtocol { + public class var identifier: String { + return "listItem" + } + public var molecule: MoleculeModelProtocol + + private enum CodingKeys: String, CodingKey { + case moleculeName + case molecule + } + + public init(with moleculeModel: MoleculeModelProtocol) { + molecule = moleculeModel + super.init() + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + molecule = try typeContainer.decodeMolecule(codingKey: .molecule) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encodeModel(molecule, forKey: .molecule) + } +} + diff --git a/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift b/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift index 9f27a918..0416ce8e 100644 --- a/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/MoleculeTableViewCell.swift @@ -16,7 +16,7 @@ import UIKit public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.setWithModel(model, delegateObject, additionalData) - guard let model = model as? ListItemModel else { return } + guard let model = model as? MoleculeListItemModel else { return } if molecule != nil { (molecule as? ModelMoleculeViewProtocol)?.setWithModel(model.molecule, delegateObject, additionalData) @@ -29,7 +29,7 @@ import UIKit } public override class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { - guard let moleculeModel = (model as? ListItemModel)?.molecule else { return "\(self)<>" } + guard let moleculeModel = (model as? MoleculeListItemModel)?.molecule else { return "\(self)<>" } let className = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(moleculeModel) as? ModelMoleculeViewProtocol.Type let moleculeName = className?.nameForReuse(moleculeModel, delegateObject) ?? moleculeModel.moleculeName ?? "" diff --git a/MVMCoreUI/Molecules/Items/TabsListItemModel.swift b/MVMCoreUI/Molecules/Items/TabsListItemModel.swift index 0158774a..c89ee1a0 100644 --- a/MVMCoreUI/Molecules/Items/TabsListItemModel.swift +++ b/MVMCoreUI/Molecules/Items/TabsListItemModel.swift @@ -8,39 +8,36 @@ import UIKit -public class TabsListItemModel: ContainerModel, ListItemModelProtocol { +public class TabsListItemModel: ListItemModel, MoleculeModelProtocol { public static var identifier: String = "tabsListItem" var tabs: TabsModel - var molecules: [[ListItemModelProtocol]] - - public var backgroundColor: Color? - public var hideArrow: Bool? = true - public var line: LineModel? = LineModel(type: .standard) + var molecules: [[ListItemModelProtocol & MoleculeModelProtocol]] private enum CodingKeys: String, CodingKey { case moleculeName case tabs case molecules - case backgroundColor - case line } - public init(with tabs: TabsModel, molecules: [[ListItemModelProtocol]]) { + public override func setDefaults() { + super.setDefaults() + hideArrow = true + action = nil + style = nil + topMarginPadding = 8 + bottomMarginPadding = 0 + } + + public init(with tabs: TabsModel, molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]) { self.tabs = tabs self.molecules = molecules super.init() - self.topMarginPadding = 8 - self.bottomMarginPadding = 0 } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) tabs = try typeContainer.decode(TabsModel.self, forKey: .tabs) - molecules = try typeContainer.decodeMolecules2D(codingKey: .molecules) as! [[ListItemModelProtocol]] - backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - if let lineModel = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) { - line = lineModel - } + molecules = try typeContainer.decodeMolecules2D(codingKey: .molecules) as! [[ListItemModelProtocol & MoleculeModelProtocol]] try super.init(from: decoder) } @@ -50,7 +47,5 @@ public class TabsListItemModel: ContainerModel, ListItemModelProtocol { try container.encode(moleculeName, forKey: .moleculeName) try container.encode(tabs, forKey: .tabs) try container.encodeModels2D(molecules, forKey: .molecules) - try container.encode(backgroundColor, forKey: .backgroundColor) - try container.encodeIfPresent(line, forKey: .line) } } diff --git a/MVMCoreUI/Molecules/Items/TabsTableViewCell.swift b/MVMCoreUI/Molecules/Items/TabsTableViewCell.swift index cf09eb51..8a971221 100644 --- a/MVMCoreUI/Molecules/Items/TabsTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/TabsTableViewCell.swift @@ -9,7 +9,9 @@ import UIKit @objcMembers public class TabsTableViewCell: TableViewCell { - var tabsListItemModel: TabsListItemModel? + var tabsListItemModel: TabsListItemModel? { + return listItemModel as? TabsListItemModel + } let tabs = TopTabbar(frame: .zero) var delegateObject: MVMCoreUIDelegateObject? var previousTabIndex = 0 @@ -17,11 +19,7 @@ import UIKit // MARK: - MFViewProtocol override public func setupView() { super.setupView() - guard tabs.superview == nil else { - return - } tabs.paddingBeforeFirstTab = false - tabs.translatesAutoresizingMaskIntoConstraints = false tabs.delegate = self tabs.datasource = self @@ -48,11 +46,18 @@ import UIKit super.reset() tabs.reset() } + + public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 46 + } } extension TabsTableViewCell: TopTabbarDelegate { public func shouldSelectItem(at index: Int, topTabbar: TopTabbar) -> Bool { - if let molecules = tabsListItemModel?.molecules[topTabbar.selectedIndex] { + if let model = tabsListItemModel, + let json = model.toJSON(), + let json2d = json.optionalArrayForKey("molecules") as? [[[AnyHashable: Any]]] { + let molecules = json2d[topTabbar.selectedIndex] delegateObject?.moleculeDelegate?.removeMolecules(molecules, sender: self, animation: index < tabs.selectedIndex ? .right : .left) } previousTabIndex = tabs.selectedIndex @@ -60,7 +65,10 @@ extension TabsTableViewCell: TopTabbarDelegate { } public func topTabbar(_ topTabbar: TopTabbar, didSelectItemAt index: Int) { - if let molecules = tabsListItemModel?.molecules[index] { + if let model = tabsListItemModel, + let json = model.toJSON(), + let json2d = json.optionalArrayForKey("molecules") as? [[[AnyHashable: Any]]] { + let molecules = json2d[index] delegateObject?.moleculeDelegate?.addMolecules(molecules, sender: self, animation: index < previousTabIndex ? .left : .right) } } diff --git a/MVMCoreUI/OtherHandlers/ModelMoleculeDelegateProtocol.swift b/MVMCoreUI/OtherHandlers/ModelMoleculeDelegateProtocol.swift index 8fe1caa5..d3a2fe80 100644 --- a/MVMCoreUI/OtherHandlers/ModelMoleculeDelegateProtocol.swift +++ b/MVMCoreUI/OtherHandlers/ModelMoleculeDelegateProtocol.swift @@ -23,8 +23,8 @@ public protocol MoleculeDelegateProtocol { func removeMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) //optional - func addMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) - func removeMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) + func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) + func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) } extension MoleculeDelegateProtocol { @@ -40,11 +40,11 @@ extension MoleculeDelegateProtocol { // Do nothing } - public func addMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) { + public func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) { // Do nothing } - public func removeMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) { + public func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) { // Do nothing } } diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index 3dfc935a..a04f964a 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -74,7 +74,7 @@ import Foundation MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListLeftVariableIconWithRightCaret.self, viewModelClass: ListLeftVariableIconWithRightCaretModel.self) // List items - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeTableViewCell.self, viewModelClass: ListItemModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeTableViewCell.self, viewModelClass: MoleculeListItemModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: DropDownFilterTableViewCell.self, viewModelClass: DropDownListItemModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: AccordionMoleculeTableViewCell.self, viewModelClass: AccordionListItemModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TabsTableViewCell.self, viewModelClass: TabsListItemModel.self) diff --git a/MVMCoreUI/Templates/ListPageTemplateModel.swift b/MVMCoreUI/Templates/ListPageTemplateModel.swift index ff899319..4ce4c6f5 100644 --- a/MVMCoreUI/Templates/ListPageTemplateModel.swift +++ b/MVMCoreUI/Templates/ListPageTemplateModel.swift @@ -20,7 +20,7 @@ import Foundation public var isAtomicTabs: Bool? public var header: MoleculeModelProtocol? - public var molecules: [ListItemModelProtocol]? + public var molecules: [ListItemModelProtocol & MoleculeModelProtocol]? public var footer: MoleculeModelProtocol? public var line: LineModel? @@ -28,7 +28,7 @@ import Foundation // MARK: - Initializer //-------------------------------------------------- - public init(pageType: String, screenHeading: String?, molecules: [ListItemModelProtocol]) { + public init(pageType: String, screenHeading: String?, molecules: [ListItemModelProtocol & MoleculeModelProtocol]) { self.pageType = pageType self.screenHeading = screenHeading self.molecules = molecules @@ -57,7 +57,7 @@ import Foundation let typeContainer = try decoder.container(keyedBy: CodingKeys.self) pageType = try typeContainer.decode(String.self, forKey: .pageType) screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading) - molecules = try typeContainer.decodeMoleculesIfPresent(codingKey: .molecules) as? [ListItemModelProtocol] + molecules = try typeContainer.decodeMoleculesIfPresent(codingKey: .molecules) as? [ListItemModelProtocol & MoleculeModelProtocol] isAtomicTabs = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAtomicTabs) header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header) footer = try typeContainer.decodeMoleculeIfPresent(codingKey: .footer) diff --git a/MVMCoreUI/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Templates/MoleculeListTemplate.swift index a088d34a..01d0a5e6 100644 --- a/MVMCoreUI/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeListTemplate.swift @@ -13,7 +13,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol // MARK: - Stored Properties //-------------------------------------------------- - public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)]? + public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: (ListItemModelProtocol & MoleculeModelProtocol))]? var observer: NSKeyValueObservation? @@ -176,10 +176,10 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol public override func addMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { - var tmpMolecules = [ListItemModelProtocol]() + var tmpMolecules = [ListItemModelProtocol & MoleculeModelProtocol]() molecules.forEach { molecule in - if let data = try? JSONSerialization.data(withJSONObject: molecule), let listItemModel = try? JSONDecoder().decode(ListItemModel.self, from: data) { + if let data = try? JSONSerialization.data(withJSONObject: molecule), let listItemModel = try? JSONDecoder().decode(MoleculeListItemModel.self, from: data) { tmpMolecules.append(listItemModel) } } @@ -205,10 +205,11 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol public override func removeMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { - var tmpMolecules = [ListItemModelProtocol]() + var tmpMolecules = [ListItemModelProtocol & MoleculeModelProtocol]() molecules.forEach { molecule in - if let data = try? JSONSerialization.data(withJSONObject: molecule), let listItemModel = try? JSONDecoder().decode(ListItemModel.self, from: data) { + if let data = try? JSONSerialization.data(withJSONObject: molecule), + let listItemModel = try? JSONDecoder().decode(MoleculeListItemModel.self, from: data) { tmpMolecules.append(listItemModel) } } @@ -230,7 +231,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol view.layoutIfNeeded() } - public func addMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) { + public func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) { // This dispatch is needed to fix a race condition that can occur if this function is called during the table setup. DispatchQueue.main.async { @@ -252,7 +253,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } } - public func removeMolecules(_ molecules: [ListItemModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) { + public func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) { var indexPaths: [IndexPath] = [] //TODO: cehck for molecule protocola eqality @@ -274,7 +275,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol //-------------------------------------------------- /// Returns the (identifier, class) of the molecule for the given map. - func getMoleculeInfo(with listItem: ListItemModelProtocol?) -> (identifier: String, class: AnyClass, molecule: ListItemModelProtocol)? { + func getMoleculeInfo(with listItem: (ListItemModelProtocol & MoleculeModelProtocol)?) -> (identifier: String, class: AnyClass, molecule: ListItemModelProtocol & MoleculeModelProtocol)? { guard let listItem = listItem, let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(listItem), @@ -285,9 +286,9 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } /// Sets up the molecule list and ensures no errors loading all content. - func getMoleculeInfoList() -> [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)]? { + func getMoleculeInfoList() -> [(identifier: String, class: AnyClass, molecule: (ListItemModelProtocol & MoleculeModelProtocol))]? { - var moleculeList: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol)] = [] + var moleculeList: [(identifier: String, class: AnyClass, molecule: ListItemModelProtocol & MoleculeModelProtocol)] = [] if let molecules = templateModel?.molecules { for molecule in molecules { From adaa9ca1f3c5fbf6e255c9ecfc489143bd9cede2 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 13 Feb 2020 10:45:00 -0500 Subject: [PATCH 41/57] Bug fixes --- .../Items => BaseClasses}/TableViewCell.swift | 23 +++++++++++++------ .../ThreeLayerTableViewController.swift | 2 ++ .../Views/Container/ContainerModel.swift | 5 ++-- .../ListItemModelProtocol.swift | 2 +- 4 files changed, 22 insertions(+), 10 deletions(-) rename MVMCoreUI/{Molecules/Items => BaseClasses}/TableViewCell.swift (96%) diff --git a/MVMCoreUI/Molecules/Items/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift similarity index 96% rename from MVMCoreUI/Molecules/Items/TableViewCell.swift rename to MVMCoreUI/BaseClasses/TableViewCell.swift index cd8a3cdf..fe06a05a 100644 --- a/MVMCoreUI/Molecules/Items/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -28,6 +28,8 @@ import UIKit private var heroAccessoryCenter: CGPoint? + private var initialSetupPerformed = false + // MARK: - Styling open func style(with styleString: String?) { guard let styleString = styleString else { @@ -102,12 +104,19 @@ import UIKit // MARK: - Inits public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) - setupView() + initialSetup() } public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) - setupView() + initialSetup() + } + + public func initialSetup() { + if !initialSetupPerformed { + initialSetupPerformed = true + setupView() + } } // MARK: - MFViewProtocol @@ -151,10 +160,6 @@ import UIKit self.listItemModel = model style(with: model.style) - if let backgroundColor = model.backgroundColor { - self.backgroundColor = backgroundColor.uiColor - } - // Add the caret if there is an action and it's not declared hidden. if !customAccessoryView { if let _ = model.action, !(model.hideArrow ?? false) { @@ -169,11 +174,15 @@ import UIKit addSeparatorsIfNeeded() bottomSeparatorView?.setWithModel(separator, nil, nil) } + + if let moleculeModel = model as? MoleculeModelProtocol, + let backgroundColor = moleculeModel.backgroundColor { + self.backgroundColor = backgroundColor.uiColor + } } open func reset() { molecule?.reset?() - styleStandard() backgroundColor = .white } diff --git a/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift b/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift index 3176df92..ae3d2fac 100644 --- a/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift +++ b/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift @@ -166,6 +166,8 @@ open class ThreeLayerTableViewController: MFProgrammaticTableViewController { } // This extra view is needed because of the wonkiness of apple's table header. Things breaks if using autolayout. + headerView.setNeedsLayout() + headerView.layoutIfNeeded() MVMCoreUIUtility.sizeView(toFit: headerView) let tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: MVMCoreUIUtility.getWidth(), height: headerView.frame.height)) tableHeaderView.addSubview(headerView) diff --git a/MVMCoreUI/Containers/Views/Container/ContainerModel.swift b/MVMCoreUI/Containers/Views/Container/ContainerModel.swift index 1b721183..cdc6d743 100644 --- a/MVMCoreUI/Containers/Views/Container/ContainerModel.swift +++ b/MVMCoreUI/Containers/Views/Container/ContainerModel.swift @@ -48,7 +48,8 @@ public class ContainerModel: ContainerModelProtocol, Codable { try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: horizontalAlignment), forKey: .horizontalAlignment) try container.encodeIfPresent(useHorizontalMargins, forKey: .useHorizontalMargins) try container.encodeIfPresent(useVerticalMargins, forKey: .useVerticalMargins) - try container.encodeIfPresent(topMarginPadding, forKey: .topMarginPadding) - try container.encodeIfPresent(bottomMarginPadding, forKey: .bottomMarginPadding) + // TODO: can add this back once we have type erasures. + //try container.encodeIfPresent(topMarginPadding, forKey: .topMarginPadding) + //try container.encodeIfPresent(bottomMarginPadding, forKey: .bottomMarginPadding) } } diff --git a/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift index 020c3cbe..5d0fee08 100644 --- a/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/ListItemModelProtocol.swift @@ -9,7 +9,7 @@ import Foundation -public protocol ListItemModelProtocol: ContainerModelProtocol, MoleculeModelProtocol { +public protocol ListItemModelProtocol: ContainerModelProtocol { var line: LineModel? { get set } var action: ActionModelProtocol? { get set } var hideArrow: Bool? { get set } From c6e9c84809438d9acc558f61e6cd6b777d9e0eb3 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 13 Feb 2020 10:55:46 -0500 Subject: [PATCH 42/57] Comments update --- MVMCoreUI/BaseControllers/ViewController.swift | 3 +-- MVMCoreUI/Molecules/Items/AccordionListItemModel.swift | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 8202378b..96909c82 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -60,8 +60,7 @@ import UIKit open func setNavigationItem() { navigationItem.title = pageModel?.screenHeading - navigationItem.accessibilityLabel = pageModel?.screenHeading - + navigationItem.accessibilityLabel = pageModel?.screenHeading } open func newDataBuildScreen() { diff --git a/MVMCoreUI/Molecules/Items/AccordionListItemModel.swift b/MVMCoreUI/Molecules/Items/AccordionListItemModel.swift index 788ef919..60192c2d 100644 --- a/MVMCoreUI/Molecules/Items/AccordionListItemModel.swift +++ b/MVMCoreUI/Molecules/Items/AccordionListItemModel.swift @@ -29,7 +29,10 @@ class AccordionListItemModel: MoleculeListItemModel { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - molecules = try typeContainer.decodeMolecules(codingKey: .molecules) as! [ListItemModelProtocol & MoleculeModelProtocol] + guard let molecules = try typeContainer.decodeMolecules(codingKey: .molecules) as? [ListItemModelProtocol & MoleculeModelProtocol] else { + throw DecodingError.typeMismatch([ListItemModelProtocol & MoleculeModelProtocol].self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Casting failed")) + } + self.molecules = molecules if let hideLine = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideLineWhenExpanded) { hideLineWhenExpanded = hideLine } From 5d578b0eea0a75418945b95349af80028caa6123 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 13 Feb 2020 11:00:18 -0500 Subject: [PATCH 43/57] remove unneeded check --- MVMCoreUI/BaseControllers/ViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 96909c82..1bb06324 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -44,7 +44,7 @@ import UIKit for case let key as String in Array(loadedModules.keys) { guard modulesRequired.count > 0 else { break } - if let index = modulesRequired.firstIndex(where: {($0 as? String) == key}), index != NSNotFound { + if let index = modulesRequired.firstIndex(where: {($0 as? String) == key}) { modulesRequired.remove(at: index) } } From 8d3dea90a8b961eae183da6be3196864c1ea90f7 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 13 Feb 2020 13:26:59 -0500 Subject: [PATCH 44/57] top alert content color update --- .../MVMCoreUITopAlertExpandableView.h | 10 ++-- .../MVMCoreUITopAlertExpandableView.m | 48 +++++++++---------- .../TopAlert/MVMCoreUITopAlertMainView.h | 16 +++---- .../TopAlert/MVMCoreUITopAlertMainView.m | 41 +++++++--------- MVMCoreUI/TopAlert/MVMCoreUITopAlertView.h | 5 +- MVMCoreUI/TopAlert/MVMCoreUITopAlertView.m | 11 ++++- 6 files changed, 66 insertions(+), 65 deletions(-) diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertExpandableView.h b/MVMCoreUI/TopAlert/MVMCoreUITopAlertExpandableView.h index d1b2d470..4503872c 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertExpandableView.h +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertExpandableView.h @@ -30,16 +30,16 @@ - (nullable instancetype)initWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nullable id )animationDelegate viewToLayout:(nonnull UIView *)viewTolayout; // Used primarily for when button presses will expand or collapse. (Short view button will need to be set manually) -- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id )animationDelegate viewToLayout:(nonnull UIView *)viewTolayout; -- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id )animationDelegate viewToLayout:(nonnull UIView *)viewTolayout; +- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id )animationDelegate viewToLayout:(nonnull UIView *)viewTolayout; +- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id )animationDelegate viewToLayout:(nonnull UIView *)viewTolayout; // Used when button uses standard action map. -- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData animationDelegate:(nullable id )animationDelegate viewToLayout:(nonnull UIView *)viewTolayout; +- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData animationDelegate:(nullable id )animationDelegate viewToLayout:(nonnull UIView *)viewTolayout; // Convenience change functions - (void)setTopMessage:(nullable NSString *)topMessage; -- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData; -- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler; +- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData; +- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler; // Setters for making buttons expand and collapse the cell. - (void)setButtonPressToExpand; diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertExpandableView.m b/MVMCoreUI/TopAlert/MVMCoreUITopAlertExpandableView.m index 55bb6bfd..f215fa0b 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertExpandableView.m +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertExpandableView.m @@ -41,10 +41,10 @@ - (void)setupTopAlertWithButton:(MVMCoreUITopAlertMainView *)topAlertWithButton; // Sets up the whole view without setting button action. -- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle; +- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle; // Sets up the whole view while setting button action. -- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData; +- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData; @end @@ -97,14 +97,8 @@ [self setupTopAlertWithButton:topAlertWithButton]; // Sets the color - if (topAlertObject.backgroundColor) { - self.backgroundColor = topAlertObject.backgroundColor; - } else { - self.backgroundColor = [[MVMCoreUITopAlertView sharedGlobal] getBackgroundColorForType:topAlertObject.type]; - } - if (topAlertObject.textColor) { - self.shortView.label.textColor = topAlertObject.textColor; - } + self.shortView.label.textColor = topAlertObject.textColor ?: [[MVMCoreUITopAlertView sharedGlobal] getContentColorForType:topAlertObject.type]; + self.backgroundColor = topAlertObject.backgroundColor ?: [[MVMCoreUITopAlertView sharedGlobal] getBackgroundColorForType:topAlertObject.type]; if (topAlertWithButton.label.text.length > 0) { [self expand:NO]; @@ -112,8 +106,10 @@ } else { // Old style, has no top alert and main view is limited. - self.backgroundColor = [[MVMCoreUITopAlertView sharedGlobal] getBackgroundColorForType:topAlertObject.type]; [self setupTopMessage:nil]; - MVMCoreUITopAlertMainView *topAlertWithButton = [[MVMCoreUITopAlertMainView alloc] initWithColor:self.backgroundColor message:topAlertObject.message subMessage:nil closeButton:YES animationDelegate:animationDelegate]; + self.backgroundColor = [[MVMCoreUITopAlertView sharedGlobal] getBackgroundColorForType:topAlertObject.type]; + UIColor *contentColor = [[MVMCoreUITopAlertView sharedGlobal] getContentColorForType:topAlertObject.type]; + [self setupTopMessage:nil]; + MVMCoreUITopAlertMainView *topAlertWithButton = [[MVMCoreUITopAlertMainView alloc] initWithColor:self.backgroundColor contentColor:contentColor message:topAlertObject.message subMessage:nil closeButton:YES animationDelegate:animationDelegate]; [self setupTopAlertWithButton:topAlertWithButton]; [self expand:NO]; } @@ -121,29 +117,29 @@ return self; } -- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id )animationDelegate viewToLayout:(nonnull UIView *)viewTolayout { +- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id )animationDelegate viewToLayout:(nonnull UIView *)viewTolayout { if ([self init]) { self.animationDelegate = animationDelegate; self.viewToLayout = viewTolayout; - [self setupViewWithTopMessage:topMessage message:message subMessage:nil buttonTitle:buttonTitle]; + [self setupViewWithTopMessage:topMessage message:message subMessage:nil contentColor:contentColor buttonTitle:buttonTitle]; } return self; } -- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id )animationDelegate viewToLayout:(nonnull UIView *)viewTolayout { +- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle animationDelegate:(nullable id )animationDelegate viewToLayout:(nonnull UIView *)viewTolayout { if ([self init]) { self.animationDelegate = animationDelegate; self.viewToLayout = viewTolayout; - [self setupViewWithTopMessage:topMessage message:message subMessage:subMessage buttonTitle:buttonTitle]; + [self setupViewWithTopMessage:topMessage message:message subMessage:subMessage contentColor:contentColor buttonTitle:buttonTitle]; } return self; } -- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData animationDelegate:(nullable id )animationDelegate viewToLayout:(nonnull UIView *)viewTolayout { +- (nullable instancetype)initWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData animationDelegate:(nullable id )animationDelegate viewToLayout:(nonnull UIView *)viewTolayout { if ([self init]) { self.animationDelegate = animationDelegate; self.viewToLayout = viewTolayout; - [self setupViewWithTopMessage:topMessage message:message subMessage:subMessage actionMap:actionMap additionalData:additionalData]; + [self setupViewWithTopMessage:topMessage message:message subMessage:subMessage contentColor:contentColor actionMap:actionMap additionalData:additionalData]; } return self; } @@ -174,19 +170,19 @@ [NSLayoutConstraint constraintPinSubview:topAlertWithButton pinTop:NO topConstant:0 pinBottom:YES bottomConstant:0 pinLeft:YES leftConstant:0 pinRight:YES rightConstant:0]; } -- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle { +- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle { [self setupTopMessage:topMessage]; - MVMCoreUITopAlertMainView *topAlertWithButton = [[MVMCoreUITopAlertMainView alloc] initWithColor:[UIColor clearColor] message:message subMessage:subMessage buttonTitle:buttonTitle userActionHandler:nil]; + MVMCoreUITopAlertMainView *topAlertWithButton = [[MVMCoreUITopAlertMainView alloc] initWithColor:[UIColor clearColor] contentColor:contentColor message:message subMessage:subMessage buttonTitle:buttonTitle userActionHandler:nil]; [self setupTopAlertWithButton:topAlertWithButton]; } -- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData { +- (void)setupViewWithTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData { [self setupTopMessage:topMessage]; - MVMCoreUITopAlertMainView *topAlertWithButton = [[MVMCoreUITopAlertMainView alloc] initWithColor:[UIColor clearColor] message:message subMessage:subMessage actionMap:actionMap additionalData:additionalData]; + MVMCoreUITopAlertMainView *topAlertWithButton = [[MVMCoreUITopAlertMainView alloc] initWithColor:[UIColor clearColor] contentColor:contentColor message:message subMessage:subMessage actionMap:actionMap additionalData:additionalData]; [self setupTopAlertWithButton:topAlertWithButton]; } @@ -204,17 +200,17 @@ }]; } -- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData { +- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData { [MVMCoreDispatchUtility performBlockOnMainThread:^{ [self setTopMessage:topMessage]; - [self.buttonView setupWithMessage:message subMessage:subMessage actionMap:actionMap additionalData:additionalData]; + [self.buttonView setupWithMessage:message subMessage:subMessage color:contentColor actionMap:actionMap additionalData:additionalData]; }]; } -- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler { +- (void)setTopMessage:(nullable NSString *)topMessage message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage contentColor:(nonnull UIColor *)contentColor buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler { [MVMCoreDispatchUtility performBlockOnMainThread:^{ [self setTopMessage:topMessage]; - [self.buttonView setupWithMessage:message subMessage:subMessage buttonTitle:buttonTitle userActionHandler:userActionHandler]; + [self.buttonView setupWithMessage:message subMessage:subMessage color:contentColor buttonTitle:buttonTitle userActionHandler:userActionHandler]; }]; } diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.h b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.h index 50dd9b26..4842fc32 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.h +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.h @@ -22,16 +22,16 @@ // Standard - (nullable instancetype)initWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nullable id )animationDelegate; -- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate; +- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nullable UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate; // inits with images -- (nullable instancetype)initWithColor:(nonnull UIColor *)color imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate; -- (nullable instancetype)initWithColor:(nonnull UIColor *)color imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate; +- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nullable UIColor *)contentColor imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate; +- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nullable UIColor *)contentColor imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate; // Setters for label and button. -- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData; -- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler; +- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage color:(nullable UIColor *)color actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData; +- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage color:(nullable UIColor *)color buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler; // Setters for button. - (void)setupButtonWithActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData; @@ -40,13 +40,13 @@ #pragma mark - legacy inits // Legacy init: inits with a label and button, no close button or icon. -- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData; +- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nonnull UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData; // Legacy init: inits with a label and possible icon and close button. No main button. -- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate; +- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nonnull UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate; // Legacy init: inits with a label and button, no close button or icon. If passing in a block to use for the button, the top alert delegate button functions will not be called. -- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler; +- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nonnull UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler; @end diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m index e51ffc83..85db522b 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m @@ -60,52 +60,49 @@ - (nullable instancetype)initWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nullable id )animationDelegate { if ([self init]) { - if (topAlertObject.backgroundColor) { - self.backgroundColor = topAlertObject.backgroundColor; - } else { - self.backgroundColor = [[MVMCoreUITopAlertView sharedGlobal] getBackgroundColorForType:topAlertObject.type]; - } + UIColor *contentColor = topAlertObject.textColor ?: [[MVMCoreUITopAlertView sharedGlobal] getContentColorForType:topAlertObject.type]; + self.backgroundColor = topAlertObject.backgroundColor ?: [[MVMCoreUITopAlertView sharedGlobal] getBackgroundColorForType:topAlertObject.type]; [self setupViewWithLabelAndImage:topAlertObject.imageNameOrURL topImage:topAlertObject.aboveTextImageString]; [self setupCloseButton:topAlertObject.useCloseButton animationDelegate:animationDelegate]; - [self setupWithMessage:topAlertObject.title subMessage:topAlertObject.message color:topAlertObject.textColor actionMap:topAlertObject.buttonMap additionalData:topAlertObject.additionalData]; + [self setupWithMessage:topAlertObject.title subMessage:topAlertObject.message color:contentColor actionMap:topAlertObject.buttonMap additionalData:topAlertObject.additionalData]; } return self; } -- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate { +- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nullable UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate { // Handles all scenarios. if ([self init]) { self.backgroundColor = color; [self setupViewWithLabelAndImage:nil topImage:nil]; [self setupCloseButton:closeButton animationDelegate:animationDelegate]; - [self setupWithMessage:message subMessage:subMessage actionMap:actionMap additionalData:additionalData]; + [self setupWithMessage:message subMessage:subMessage color:contentColor actionMap:actionMap additionalData:additionalData]; } return self; } #pragma mark - inits with images -- (nullable instancetype)initWithColor:(nonnull UIColor *)color imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate { +- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nullable UIColor *)contentColor imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate { // Handles all scenarios. if ([self init]) { self.backgroundColor = color; [self setupViewWithLabelAndImage:imageURL topImage:nil]; [self setupCloseButton:closeButton animationDelegate:animationDelegate]; - [self setupWithMessage:message subMessage:subMessage actionMap:actionMap additionalData:additionalData]; + [self setupWithMessage:message subMessage:subMessage color:contentColor actionMap:actionMap additionalData:additionalData]; } return self; } -- (nullable instancetype)initWithColor:(nonnull UIColor *)color imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate { +- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nullable UIColor *)contentColor imageURL:(nullable NSString *)imageURL message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate { // No main button. if ([self init]) { self.backgroundColor = color; [self setupViewWithLabelAndImage:imageURL topImage:nil]; [self setupCloseButton:closeButton animationDelegate:animationDelegate]; - [self setupWithMessage:message subMessage:subMessage buttonTitle:nil userActionHandler:NULL]; + [self setupWithMessage:message subMessage:subMessage color:contentColor buttonTitle:nil userActionHandler:NULL]; } return self; } @@ -241,17 +238,13 @@ }]; } -- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData { - [self setupWithMessage:message subMessage:subMessage color:nil actionMap:actionMap additionalData:additionalData]; -} - -- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler { +- (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage color:(nullable UIColor *)color buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler { self.message = message; self.subMessage = subMessage; [MVMCoreDispatchUtility performBlockOnMainThread:^{ // Sets the string - self.label.attributedText = [MVMCoreUITopAlertBaseView getStringForMessage:message subMessage:subMessage color:nil]; + self.label.attributedText = [MVMCoreUITopAlertBaseView getStringForMessage:message subMessage:subMessage color:color]; // Sets the button [self setupButtonWithButtonTitle:buttonTitle userActionHandler:userActionHandler]; @@ -284,36 +277,36 @@ #pragma mark - legacy inits -- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData { +- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nonnull UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData { // No icon or close button. if ([self init]) { self.backgroundColor = color; [self setupViewWithLabelAndImage:nil topImage:nil]; - [self setupWithMessage:message subMessage:subMessage actionMap:actionMap additionalData:additionalData]; + [self setupWithMessage:message subMessage:subMessage color:contentColor actionMap:actionMap additionalData:additionalData]; } return self; } -- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate { +- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nonnull UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage closeButton:(BOOL)closeButton animationDelegate:(nullable id )animationDelegate { // No main button. if ([self init]) { self.backgroundColor = color; [self setupViewWithLabelAndImage:nil topImage:nil]; [self setupCloseButton:closeButton animationDelegate:animationDelegate]; - [self setupWithMessage:message subMessage:subMessage buttonTitle:nil userActionHandler:NULL]; + [self setupWithMessage:message subMessage:subMessage color:contentColor buttonTitle:nil userActionHandler:NULL]; } return self; } -- (nullable instancetype)initWithColor:(nonnull UIColor *)color message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler { +- (nullable instancetype)initWithColor:(nonnull UIColor *)color contentColor:(nonnull UIColor *)contentColor message:(nullable NSString *)message subMessage:(nullable NSString *)subMessage buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler { // No icon or close button. Custom button action. if ([self init]) { self.backgroundColor = color; [self setupViewWithLabelAndImage:nil topImage:nil]; - [self setupWithMessage:message subMessage:subMessage buttonTitle:buttonTitle userActionHandler:userActionHandler]; + [self setupWithMessage:message subMessage:subMessage color:contentColor buttonTitle:buttonTitle userActionHandler:userActionHandler]; } return self; } diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertView.h b/MVMCoreUI/TopAlert/MVMCoreUITopAlertView.h index 9850cca3..ca9520f3 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertView.h +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertView.h @@ -47,9 +47,12 @@ // Can be subclassed for custom views. - (nonnull MVMCoreUITopAlertBaseView *)topAlertViewForTopAlertObject:(nullable MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nonnull id )animationDelegate statusBarColor:(UIColor *_Nullable *_Nullable)statusBarColor; -// Get the background color based on the type +/// Get the background color based on the type - (nonnull UIColor *)getBackgroundColorForType:(nullable NSString *)type; +/// Get the content color based on the type +- (nonnull UIColor *)getContentColorForType:(nullable NSString *)type; + // Set the status bar color. Used for updating the status bar when the view changes. - (void)setStatusBarColor:(nullable UIColor *)statusBarColor statusBarStyle:(UIStatusBarStyle)style; diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertView.m b/MVMCoreUI/TopAlert/MVMCoreUITopAlertView.m index b65f7423..947e6ffc 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertView.m +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertView.m @@ -114,6 +114,14 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed."; } } +- (nonnull UIColor *)getContentColorForType:(nullable NSString *)type { + if ([type isEqualToString:ValueTypeError]) { + return [UIColor blackColor]; + } else { + return [UIColor whiteColor]; + } +} + - (void)showWithTopAlertObject:(nullable MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nonnull id )animationDelegate completionHandler:(void (^ __nullable)(BOOL finished))completionHandler { self.animationDelegate = animationDelegate; @@ -126,7 +134,8 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed."; MVMCoreUITopAlertBaseView *view = [self topAlertViewForTopAlertObject:topAlertObject animationDelegate:animationDelegate statusBarColor:&statusBarColor]; if (!statusBarColor) { statusBarColor = [UIColor whiteColor]; - } + } +#warning This logic is incomplete, it is possible to show the wrong status bar color here if the background is yellow or pumpkin. UIStatusBarStyle statusBarStyle = statusBarColor == [UIColor whiteColor] ? UIStatusBarStyleDefault : UIStatusBarStyleLightContent; [self setStatusBarColor:statusBarColor statusBarStyle:statusBarStyle]; [self showAlertView:view topAlertObject:topAlertObject completionHandler:completionHandler]; From c4c96dc4d4f641ce343a48d260555b1298c7c5b0 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 13 Feb 2020 15:43:59 -0500 Subject: [PATCH 45/57] x color fix --- MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m index 85db522b..5b87d163 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m @@ -170,7 +170,7 @@ if (closeButton && !self.closeButton) { self.closeButton = [self addCloseButtonWithAnimationDelegate:animationDelegate]; - [self.closeButton setTintColor:self.contentColor ?:[UIColor whiteColor]]; + [self.closeButton setTintColor:self.contentColor ?: [UIColor whiteColor]]; } else if (!closeButton && self.closeButton) { [self.closeButton removeFromSuperview]; self.closeButton = nil; @@ -241,11 +241,17 @@ - (void)setupWithMessage:(nullable NSString *)message subMessage:(nullable NSString *)subMessage color:(nullable UIColor *)color buttonTitle:(nullable NSString *)buttonTitle userActionHandler:(nullable void (^)(id _Nonnull sender))userActionHandler { self.message = message; self.subMessage = subMessage; + self.contentColor = color; [MVMCoreDispatchUtility performBlockOnMainThread:^{ // Sets the string self.label.attributedText = [MVMCoreUITopAlertBaseView getStringForMessage:message subMessage:subMessage color:color]; + // Sets the color + if (color) { + [self.closeButton setTintColor:color]; + } + // Sets the button [self setupButtonWithButtonTitle:buttonTitle userActionHandler:userActionHandler]; }]; @@ -294,8 +300,8 @@ if ([self init]) { self.backgroundColor = color; [self setupViewWithLabelAndImage:nil topImage:nil]; - [self setupCloseButton:closeButton animationDelegate:animationDelegate]; [self setupWithMessage:message subMessage:subMessage color:contentColor buttonTitle:nil userActionHandler:NULL]; + [self setupCloseButton:closeButton animationDelegate:animationDelegate]; } return self; } From ee85a8972e3dfa8a00ae9c9091d03d830aa2cb7e Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 14 Feb 2020 08:58:32 -0500 Subject: [PATCH 46/57] relaigning key name with legacy name. --- MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift index 5f60081e..1030fb8c 100644 --- a/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift @@ -37,7 +37,7 @@ import Foundation private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor - case title + case title = "label" case isEnabled case feedback case errorMessage = "errorMsg" From e431ea2de9690a6ae61ed90c9ec9c538cff6af0e Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Fri, 14 Feb 2020 15:56:36 -0500 Subject: [PATCH 47/57] fixes --- MVMCoreUI.xcodeproj/project.pbxproj | 4 + MVMCoreUI/Atoms/Views/ImageViewModel.swift | 24 ++++- MVMCoreUI/Atoms/Views/Label/LabelModel.swift | 6 +- MVMCoreUI/Atoms/Views/MFLoadImageView.swift | 48 +++++++++ .../HeadlineBodyModel.swift | 1 + .../MVMCoreUIViewControllerMappingObject.m | 4 +- .../Templates/IsaacLandingTemplate.swift | 100 ++++++++++++++++++ 7 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 MVMCoreUI/Templates/IsaacLandingTemplate.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index d114d2ae..6ac575a6 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -50,6 +50,7 @@ 0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0198F79E225679870066C936 /* FormValidationProtocol.swift */; }; 0198F7A62256A80B0066C936 /* MFRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 0198F7A02256A80A0066C936 /* MFRadioButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0198F7A22256A80A0066C936 /* MFRadioButton.m */; }; + 01B5E6B023F5F276005B5839 /* IsaacLandingTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01B5E6AF23F5F276005B5839 /* IsaacLandingTemplate.swift */; }; 01C851D323CF9E740021F976 /* LabelToggleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01C851D223CF9E740021F976 /* LabelToggleModel.swift */; }; 01E569D3223FFFA500327251 /* ThreeLayerViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */; }; @@ -382,6 +383,7 @@ 0198F79E225679870066C936 /* FormValidationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidationProtocol.swift; sourceTree = ""; }; 0198F7A02256A80A0066C936 /* MFRadioButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFRadioButton.h; sourceTree = ""; }; 0198F7A22256A80A0066C936 /* MFRadioButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFRadioButton.m; sourceTree = ""; }; + 01B5E6AF23F5F276005B5839 /* IsaacLandingTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IsaacLandingTemplate.swift; sourceTree = ""; }; 01C851D223CF9E740021F976 /* LabelToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelToggleModel.swift; sourceTree = ""; }; 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeModelProtocol.swift; sourceTree = ""; }; 01EB368823609801006832FA /* LabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelModel.swift; sourceTree = ""; }; @@ -1068,6 +1070,7 @@ D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */, 014AA72A23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift */, D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */, + 01B5E6AF23F5F276005B5839 /* IsaacLandingTemplate.swift */, ); path = Templates; sourceTree = ""; @@ -1810,6 +1813,7 @@ D28A839123CD4FD400DFE4FC /* CornerLabelsModel.swift in Sources */, 012A88F123985E0100FE3DA1 /* Color.swift in Sources */, 012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */, + 01B5E6B023F5F276005B5839 /* IsaacLandingTemplate.swift in Sources */, D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */, C003506123AA94CD00B6AC29 /* Button.swift in Sources */, DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Views/ImageViewModel.swift b/MVMCoreUI/Atoms/Views/ImageViewModel.swift index ce46a930..f8443da5 100644 --- a/MVMCoreUI/Atoms/Views/ImageViewModel.swift +++ b/MVMCoreUI/Atoms/Views/ImageViewModel.swift @@ -11,11 +11,33 @@ import Foundation @objcMembers public class ImageViewModel: MoleculeModelProtocol { public static var identifier: String = "image" public var backgroundColor: Color? - + 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? + public var contentMode: ContentMode? + + public enum ContentMode : String, Codable { + case scaleToFill + case scaleAspectFit // contents scaled to fit with fixed aspect. remainder is transparent + case scaleAspectFill // contents scaled to fill with fixed aspect. some portion of content may be clipped. + case redraw // redraw on bounds change (calls -setNeedsDisplay) + case center // contents remain same size. positioned adjusted. + case top + case bottom + case left + case right + case topLeft + case topRight + case bottomLeft + case bottomRight + } + + public init(image: String) { + self.image = image + moleculeName = Self.identifier + } } diff --git a/MVMCoreUI/Atoms/Views/Label/LabelModel.swift b/MVMCoreUI/Atoms/Views/Label/LabelModel.swift index 731b23da..a177f414 100644 --- a/MVMCoreUI/Atoms/Views/Label/LabelModel.swift +++ b/MVMCoreUI/Atoms/Views/Label/LabelModel.swift @@ -45,7 +45,11 @@ import Foundation enum AttributeTypeKey: String, CodingKey { case type } - + + public init(text: String) { + self.text = text + } + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName) diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift index 1c54b891..d46a5150 100644 --- a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift @@ -232,6 +232,54 @@ import UIKit imageView.animatedImage = nil loadImage(withName: imageModel.image, format: imageModel.imageFormat, width: width as NSNumber?, height: height as NSNumber?, customFallbackImage: imageModel.fallbackImage) } + setContentMode(imageModel) + } + + func setContentMode(_ model: ImageViewModel?) { + switch model?.contentMode { + case .scaleToFill: + imageView.contentMode = .scaleToFill + break + case .scaleAspectFit: + imageView.contentMode = .scaleAspectFit + break + case .scaleAspectFill: + imageView.contentMode = .scaleAspectFill + break + case .redraw: + imageView.contentMode = .redraw + break + case .center: + imageView.contentMode = .center + break + case .top: + imageView.contentMode = .top + break + case .bottom: + imageView.contentMode = .bottom + break + case .left: + imageView.contentMode = .left + break + case .right: + imageView.contentMode = .right + break + case .topLeft: + imageView.contentMode = .topLeft + break + case .topRight: + imageView.contentMode = .topRight + break + case .bottomLeft: + imageView.contentMode = .bottomLeft + break + case .bottomRight: + imageView.contentMode = .bottomRight + break + default: + break + } + } // MARK: - MVMCoreUIMoleculeViewProtocol functions diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift index 1fbe98e7..8d649995 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift @@ -18,5 +18,6 @@ import Foundation public init(headline: LabelModel) { self.headline = headline + moleculeName = Self.identifier } } diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m index 7bdccc8e..fb29096c 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m @@ -22,8 +22,8 @@ @"stack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackTemplate class]], @"centerMoleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackCenteredTemplate class]], @"list" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeListTemplate class]], - @"threeLayer" : - [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[ThreeLayerTemplate class]] + @"threeLayer": [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[ThreeLayerTemplate class]], + @"isaacLanding": [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[IsaacLandingTemplate class]] } mutableCopy]; }); return viewControllerMapping; diff --git a/MVMCoreUI/Templates/IsaacLandingTemplate.swift b/MVMCoreUI/Templates/IsaacLandingTemplate.swift new file mode 100644 index 00000000..f6924c12 --- /dev/null +++ b/MVMCoreUI/Templates/IsaacLandingTemplate.swift @@ -0,0 +1,100 @@ +// +// IsaacLandingTemplate.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 2/13/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + + +open class IsaacLandingTemplate: MoleculeListTemplate { + + func parseTemplateJSON() throws { + + } + + @objc public override func parsePageJSON() throws { + guard let pageJSON = self.loadObject?.pageJSON else { return } + + var listItems: [MoleculeListItemModel] = [] + (pageJSON.arrayForKey("items") as? [[AnyHashable: Any]])?.forEach { (itemJson) in + if let item = getListItem(itemJson) { + listItems.append(item) + } + } + + let template = ListPageTemplateModel(pageType: pageJSON.stringForkey(KeyPageType), + screenHeading: pageJSON.stringForkey(KeyScreenHeading), + molecules: listItems) + + + self.templateModel = template + } + + func getListItem(_ moleculeJson: [AnyHashable: Any]) -> MoleculeListItemModel? { + guard let type = moleculeJson.optionalStringForKey("type") else { + return nil + } + + if type == "rewards" { + return getRewardListItem(moleculeJson) + } + + let textcolor = moleculeJson.optionalStringForKey("textColor") + var stackItems: [MoleculeStackItemModel] = [] + + let titleLabel = LabelModel(text: moleculeJson.stringForkey(KeyTitle)) + titleLabel.fontName = "NHaasGroteskDSStd-75Bd" + titleLabel.textColor = textcolor + titleLabel.fontSize = (type == "topHeader") ? 70.0 : 25.0 + + + let messageLabel = LabelModel(text: moleculeJson.stringForkey("message")) + messageLabel.fontStyle = "B2" + messageLabel.textColor = textcolor + + let headlineBodyModel = HeadlineBodyModel(headline: titleLabel) + headlineBodyModel.body = messageLabel + + if let linkMap = moleculeJson.optionalDictionaryForKey("link") { + do { + let linkDict: [String : Any] = ["title": linkMap.stringForkey(KeyTitle), + "action": linkMap] + let data = try JSONSerialization.data(withJSONObject: linkDict) + let decoder = JSONDecoder() + let linkModel = try decoder.decode(LinkModel.self, from: data) + linkModel.textColor = Color(uiColor: UIColor.mfGet(forHex: textcolor ?? "#FFFFFF")) + let headlineBodyLinkModel = HeadlineBodyLinkModel(headlineBody: headlineBodyModel, + link: linkModel) + stackItems.append(MoleculeStackItemModel(with: headlineBodyLinkModel)) + } catch { + + } + } else { + stackItems.append(MoleculeStackItemModel(with: headlineBodyModel)) + } + + if let imageurl = moleculeJson.optionalStringForKey("imageUrl") { + let imageModel = ImageViewModel(image: imageurl) + imageModel.height = moleculeJson.optionalCGFloatForKey("imageHeight") ?? 300 + imageModel.imageFormat = "jpeg" + imageModel.contentMode = .scaleAspectFit + stackItems.append(MoleculeStackItemModel(with: imageModel)) + } + + let stack = MoleculeStackModel(molecules: stackItems) + let listItem = MoleculeListItemModel(with: stack) + + let backgroudColorString = moleculeJson.optionalStringForKey("backgroundColor") ?? "#000000" + listItem.backgroundColor = Color(uiColor: UIColor.mfGet(forHex: backgroudColorString)) + listItem.line = LineModel(type: .none) + return listItem + } + + func getRewardListItem(_ moleculeJson: [AnyHashable: Any]) -> MoleculeListItemModel? { + return nil + } +} + From 87dcde33176eead722a6c6399f9496f6a6d14ff4 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 17 Feb 2020 12:11:57 -0500 Subject: [PATCH 48/57] WIP --- MVMCoreUI/Atoms/Buttons/ButtonModel.swift | 8 + .../Views/Label/LabelAttributeModel.swift | 8 +- MVMCoreUI/Atoms/Views/Label/LabelModel.swift | 1 + MVMCoreUI/BaseClasses/Button.swift | 7 +- MVMCoreUI/Molecules/FooterModel.swift | 2 + .../TwoButtonViewModel.swift | 5 + .../Items/MoleculeStackItemModel.swift | 2 + .../Templates/IsaacLandingTemplate.swift | 190 +++++++++++++----- 8 files changed, 171 insertions(+), 52 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift index cfe8bb2f..5640996f 100644 --- a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift @@ -39,12 +39,20 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { init(with title: String, action: ActionModelProtocol) { self.title = title self.action = action + moleculeName = Self.identifier } init(secondaryButtonWith title: String, action: ActionModelProtocol) { self.title = title self.action = action style = .secondary + moleculeName = Self.identifier + } + + init(primaryButtonWith title: String, action: ActionModelProtocol) { + self.title = title + self.action = action + style = .primary } private enum CodingKeys: String, CodingKey { diff --git a/MVMCoreUI/Atoms/Views/Label/LabelAttributeModel.swift b/MVMCoreUI/Atoms/Views/Label/LabelAttributeModel.swift index 22bb10d8..3c073b2f 100644 --- a/MVMCoreUI/Atoms/Views/Label/LabelAttributeModel.swift +++ b/MVMCoreUI/Atoms/Views/Label/LabelAttributeModel.swift @@ -28,7 +28,13 @@ import Foundation var type: String var location: Int var length: Int - + + init(_ type: String, _ location: Int, _ length: Int) { + self.type = type + self.location = location + self.length = length + } + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- diff --git a/MVMCoreUI/Atoms/Views/Label/LabelModel.swift b/MVMCoreUI/Atoms/Views/Label/LabelModel.swift index a177f414..76597b44 100644 --- a/MVMCoreUI/Atoms/Views/Label/LabelModel.swift +++ b/MVMCoreUI/Atoms/Views/Label/LabelModel.swift @@ -48,6 +48,7 @@ import Foundation public init(text: String) { self.text = text + moleculeName = Self.identifier } required public init(from decoder: Decoder) throws { diff --git a/MVMCoreUI/BaseClasses/Button.swift b/MVMCoreUI/BaseClasses/Button.swift index a780151a..24378184 100644 --- a/MVMCoreUI/BaseClasses/Button.swift +++ b/MVMCoreUI/BaseClasses/Button.swift @@ -88,12 +88,13 @@ public typealias ButtonAction = (Button) -> () // MARK:- ModelMoleculeViewProtocol open func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { self.model = model - if let backgroundColor = model?.backgroundColor { - self.backgroundColor = backgroundColor.uiColor - } guard let model = model as? ButtonModelProtocol else { return } isEnabled = model.enabled + + if let backgroundColor = (model as? MoleculeModelProtocol)?.backgroundColor { + self.backgroundColor = backgroundColor.uiColor + } set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) } diff --git a/MVMCoreUI/Molecules/FooterModel.swift b/MVMCoreUI/Molecules/FooterModel.swift index d61d1194..57a81f8b 100644 --- a/MVMCoreUI/Molecules/FooterModel.swift +++ b/MVMCoreUI/Molecules/FooterModel.swift @@ -12,6 +12,7 @@ import Foundation @objcMembers public class FooterModel: MoleculeContainerModel, MoleculeModelProtocol { public static var identifier: String = "footer" public var backgroundColor: Color? + public var moleculeName: String? private enum CodingKeys: String, CodingKey { case moleculeName @@ -37,6 +38,7 @@ import Foundation public override init(with moleculeModel: MoleculeModelProtocol) { super.init(with: moleculeModel) setDefaults() + moleculeName = Self.identifier } required public init(from decoder: Decoder) throws { diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift index 5938692b..70d3f743 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift @@ -10,6 +10,7 @@ import UIKit public class TwoButtonViewModel: MoleculeModelProtocol { public static var identifier: String = "twoButtonView" + public var moleculeName: String? public var backgroundColor: Color? public var primaryButton: ButtonModel? public var secondaryButton: ButtonModel? @@ -21,6 +22,10 @@ public class TwoButtonViewModel: MoleculeModelProtocol { case secondaryButton } + init() { + moleculeName = Self.identifier + } + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) diff --git a/MVMCoreUI/Molecules/Items/MoleculeStackItemModel.swift b/MVMCoreUI/Molecules/Items/MoleculeStackItemModel.swift index 4731ef34..2b23f405 100644 --- a/MVMCoreUI/Molecules/Items/MoleculeStackItemModel.swift +++ b/MVMCoreUI/Molecules/Items/MoleculeStackItemModel.swift @@ -13,6 +13,7 @@ import Foundation public var backgroundColor: Color? public var spacing: CGFloat? public var percent: Int? + public var moleculeName: String? public var gone: Bool = false private enum CodingKeys: String, CodingKey { @@ -24,6 +25,7 @@ import Foundation public override init(with moleculeModel: MoleculeModelProtocol) { super.init(with: moleculeModel) + moleculeName = Self.identifier } required public init(from decoder: Decoder) throws { diff --git a/MVMCoreUI/Templates/IsaacLandingTemplate.swift b/MVMCoreUI/Templates/IsaacLandingTemplate.swift index f6924c12..99c716d6 100644 --- a/MVMCoreUI/Templates/IsaacLandingTemplate.swift +++ b/MVMCoreUI/Templates/IsaacLandingTemplate.swift @@ -29,8 +29,59 @@ open class IsaacLandingTemplate: MoleculeListTemplate { screenHeading: pageJSON.stringForkey(KeyScreenHeading), molecules: listItems) - + let backgroudColorString = pageJSON.optionalStringForKey("backgroundColor") ?? "#000000" + template.footer = setFooter(pageJSON, template) + //print(template.toJSONString()) self.templateModel = template + + DispatchQueue.main.async { [weak self] in + self?.view.backgroundColor = UIColor.mfGet(forHex: backgroudColorString) + } + } + + func setFooter(_ pageJSON: [AnyHashable: Any], _ template: ListPageTemplateModel) -> FooterModel? { + + let primaryButtonBGColor = pageJSON.optionalStringForKey("primaryButtonBGColor") ?? "#FFFFFF" + let primaryButtonTextColor = pageJSON.optionalStringForKey("primaryButtonTextColor") ?? "#000000" + + let backgroudColorString = pageJSON.optionalStringForKey("backgroundColor") ?? "#000000" + if let buttonMap = pageJSON.optionalDictionaryForKey("ButtonMap") { + let twoButtonModel = TwoButtonViewModel() + + if let primarybutton = buttonMap.optionalDictionaryForKey(KeyPrimaryButton) { + let buttonDict: [String : Any] = ["title": primarybutton.stringForkey(KeyTitle), + "action": primarybutton, + "moleculeName": "button"] + if let data = try? JSONSerialization.data(withJSONObject: buttonDict) { + let decoder = JSONDecoder() + twoButtonModel.primaryButton = try? decoder.decode(ButtonModel.self, from: data) + twoButtonModel.primaryButton?.backgroundColor = Color(uiColor: UIColor.mfGet(forHex: primaryButtonBGColor)) + twoButtonModel.primaryButton?.textColor = Color(uiColor: UIColor.mfGet(forHex: primaryButtonTextColor)) + } + } + if let secondaryButton = buttonMap.optionalDictionaryForKey(KeySecondaryButton) { + let buttonDict: [String : Any] = ["title": secondaryButton.stringForkey(KeyTitle), + "action": secondaryButton, + "moleculeName": "button"] + if let data = try? JSONSerialization.data(withJSONObject: buttonDict) { + let decoder = JSONDecoder() + twoButtonModel.secondaryButton = try? decoder.decode(ButtonModel.self, from: data) + twoButtonModel.secondaryButton?.backgroundColor = Color(uiColor: UIColor.mfGet(forHex: primaryButtonTextColor)) + twoButtonModel.secondaryButton?.textColor = Color(uiColor: UIColor.mfGet(forHex:primaryButtonBGColor)) + } + } + + let footerStack = MoleculeStackModel(molecules: [MoleculeStackItemModel(with:LineModel(type: .standard)), + MoleculeStackItemModel(with: twoButtonModel)]) + footerStack.useHorizontalMargins = false + footerStack.spacing = PaddingFour + + let footer = FooterModel(with: footerStack) + footer.useHorizontalMargins = false + footer.backgroundColor = Color(uiColor: UIColor.mfGet(forHex: backgroudColorString)) + return footer + } + return nil } func getListItem(_ moleculeJson: [AnyHashable: Any]) -> MoleculeListItemModel? { @@ -40,61 +91,104 @@ open class IsaacLandingTemplate: MoleculeListTemplate { if type == "rewards" { return getRewardListItem(moleculeJson) - } - - let textcolor = moleculeJson.optionalStringForKey("textColor") - var stackItems: [MoleculeStackItemModel] = [] - - let titleLabel = LabelModel(text: moleculeJson.stringForkey(KeyTitle)) - titleLabel.fontName = "NHaasGroteskDSStd-75Bd" - titleLabel.textColor = textcolor - titleLabel.fontSize = (type == "topHeader") ? 70.0 : 25.0 - - - let messageLabel = LabelModel(text: moleculeJson.stringForkey("message")) - messageLabel.fontStyle = "B2" - messageLabel.textColor = textcolor - - let headlineBodyModel = HeadlineBodyModel(headline: titleLabel) - headlineBodyModel.body = messageLabel - - if let linkMap = moleculeJson.optionalDictionaryForKey("link") { - do { - let linkDict: [String : Any] = ["title": linkMap.stringForkey(KeyTitle), - "action": linkMap] - let data = try JSONSerialization.data(withJSONObject: linkDict) - let decoder = JSONDecoder() - let linkModel = try decoder.decode(LinkModel.self, from: data) - linkModel.textColor = Color(uiColor: UIColor.mfGet(forHex: textcolor ?? "#FFFFFF")) - let headlineBodyLinkModel = HeadlineBodyLinkModel(headlineBody: headlineBodyModel, - link: linkModel) - stackItems.append(MoleculeStackItemModel(with: headlineBodyLinkModel)) - } catch { - - } } else { - stackItems.append(MoleculeStackItemModel(with: headlineBodyModel)) + return getTitleImageListItem(moleculeJson, type) } + } - if let imageurl = moleculeJson.optionalStringForKey("imageUrl") { - let imageModel = ImageViewModel(image: imageurl) - imageModel.height = moleculeJson.optionalCGFloatForKey("imageHeight") ?? 300 - imageModel.imageFormat = "jpeg" - imageModel.contentMode = .scaleAspectFit - stackItems.append(MoleculeStackItemModel(with: imageModel)) - } + func getTitleImageListItem(_ moleculeJson: [AnyHashable: Any], _ type: String) -> MoleculeListItemModel? { + let textcolor = moleculeJson.optionalStringForKey("textColor") + var stackItems: [MoleculeStackItemModel] = [] - let stack = MoleculeStackModel(molecules: stackItems) - let listItem = MoleculeListItemModel(with: stack) + let titleLabel = LabelModel(text: moleculeJson.stringForkey(KeyTitle)) + titleLabel.fontName = "NHaasGroteskDSStd-75Bd" + titleLabel.textColor = textcolor + titleLabel.fontSize = (type == "topHeader") ? 70.0 : 25.0 - let backgroudColorString = moleculeJson.optionalStringForKey("backgroundColor") ?? "#000000" - listItem.backgroundColor = Color(uiColor: UIColor.mfGet(forHex: backgroudColorString)) - listItem.line = LineModel(type: .none) - return listItem + let messageLabel = LabelModel(text: moleculeJson.stringForkey("message")) + messageLabel.fontStyle = "B2" + messageLabel.textColor = textcolor + + let headlineBodyModel = HeadlineBodyModel(headline: titleLabel) + headlineBodyModel.body = messageLabel + + if let linkMap = moleculeJson.optionalDictionaryForKey("link") { + do { + let linkDict: [String : Any] = ["title": linkMap.stringForkey(KeyTitle), + "action": linkMap] + let data = try JSONSerialization.data(withJSONObject: linkDict) + let decoder = JSONDecoder() + let linkModel = try decoder.decode(LinkModel.self, from: data) + linkModel.textColor = Color(uiColor: UIColor.mfGet(forHex: textcolor ?? "#FFFFFF")) + let headlineBodyLinkModel = HeadlineBodyLinkModel(headlineBody: headlineBodyModel, + link: linkModel) + stackItems.append(MoleculeStackItemModel(with: headlineBodyLinkModel)) + } catch { + stackItems.append(MoleculeStackItemModel(with: headlineBodyModel)) + } + } else { + stackItems.append(MoleculeStackItemModel(with: headlineBodyModel)) + } + + if let imageurl = moleculeJson.optionalStringForKey("imageUrl") { + let imageModel = ImageViewModel(image: imageurl) + imageModel.height = moleculeJson.optionalCGFloatForKey("imageHeight") ?? 300 + imageModel.imageFormat = "jpeg" + imageModel.contentMode = .scaleAspectFit + stackItems.append(MoleculeStackItemModel(with: imageModel)) + } + + let stack = MoleculeStackModel(molecules: stackItems) + let listItem = MoleculeListItemModel(with: stack) + + let backgroudColorString = moleculeJson.optionalStringForKey("backgroundColor") ?? "#000000" + listItem.backgroundColor = Color(uiColor: UIColor.mfGet(forHex: backgroudColorString)) + listItem.line = LineModel(type: .none) + return listItem } func getRewardListItem(_ moleculeJson: [AnyHashable: Any]) -> MoleculeListItemModel? { - return nil + + var stackItems: [MoleculeStackItemModel] = [] + + (moleculeJson.arrayForKey("rewards") as? [[AnyHashable: Any]])?.forEach { (rewardItem) in + let textcolor = rewardItem.optionalStringForKey("textColor") + + let titleLabel = LabelModel(text: rewardItem.stringForkey(KeyTitle)) + titleLabel.fontName = "NHaasGroteskDSStd-75Bd" + titleLabel.textColor = textcolor + titleLabel.fontSize = 48 + + let messageLabel = LabelModel(text: rewardItem.stringForkey("message")) + messageLabel.fontName = "NHaasGroteskDSStd-75Bd" + messageLabel.textColor = textcolor + messageLabel.fontSize = 14 + + let titleStackItem = MoleculeStackItemModel(with: titleLabel) + let messageStackItem = MoleculeStackItemModel(with: messageLabel) + + let itemStack = MoleculeStackModel(molecules: [titleStackItem, messageStackItem]) + itemStack.useVerticalMargins = false + itemStack.topMarginPadding = 0 + + itemStack.verticalAlignment = .leading + itemStack.axis = .vertical + itemStack.spacing = 0 + + stackItems.append(MoleculeStackItemModel(with: itemStack)) + } + + let stack = MoleculeStackModel(molecules: stackItems) + stack.axis = .horizontal + stack.spacing = 65 + stack.verticalAlignment = .leading + + let listItem = MoleculeListItemModel(with: stack) + let backgroudColorString = moleculeJson.optionalStringForKey("backgroundColor") ?? "#000000" + listItem.backgroundColor = Color(uiColor: UIColor.mfGet(forHex: backgroudColorString)) + listItem.line = LineModel(type: .none) + + return listItem } } From 06fe32f37b9a118fcf34fcb821f66340d93e63e8 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 17 Feb 2020 12:21:32 -0500 Subject: [PATCH 49/57] changing pumpkin to orange for design update. --- MVMCoreUI/Categories/UIColor+Extension.swift | 177 ++++++++++++++++--- MVMCoreUI/Categories/UIColor+MFConvenience.h | 1 + MVMCoreUI/Categories/UIColor+MFConvenience.m | 5 +- MVMCoreUI/TopAlert/MVMCoreUITopAlertView.m | 2 +- 4 files changed, 162 insertions(+), 23 deletions(-) diff --git a/MVMCoreUI/Categories/UIColor+Extension.swift b/MVMCoreUI/Categories/UIColor+Extension.swift index 55a10c03..94bf780d 100644 --- a/MVMCoreUI/Categories/UIColor+Extension.swift +++ b/MVMCoreUI/Categories/UIColor+Extension.swift @@ -12,24 +12,52 @@ public typealias ColorHexTuple = (uiColor: UIColor, hex: String) extension UIColor { + //-------------------------------------------------- + // MARK: - Convenience Dictionary + //-------------------------------------------------- /// Dictionary to access brand approved colors by name. public static let names: [String: ColorHexTuple] = ["black": (.mvmBlack, "#000000"), "white": (.mvmWhite, "#FFFFFF"), "red": (.mvmRed, "#D52B1E"), - "orange": (.mvmOrange, "#CC4D0F"), - "green": (.mvmGreen, "#008631"), - "blue": (.mvmBlue, "#007AB8"), - "blueGradient": (.mvmBlueGradient, "#007AB8"), + "pink": (.mvmPink, "#D90368"), + "pink33": (.mvmPink33, "#F2ABCD"), + "pink66": (.mvmPink66, "#E6589B"), + "pinkShade1": (.mvmPinkShade1, "#B31C63"), + "pinkShade2": (.mvmPinkShade2, "#830842"), + "purple": (.mvmPurple, "#8C00AC"), + "purple33": (.mvmPurple33, "#D9ABE4"), + "purple66": (.mvmPurple66, "#B356C8"), + "purpleShade1": (.mvmPurpleShade1, "#6C177F"), + "purpleShade2": (.mvmPurpleShade2, "#4A0E58"), + "green": (.mvmGreen, "#008330"), + "green33": (.mvmGreen33, "#ABE4BF"), + "green66": (.mvmGreen66, "#57C880"), + "greenShade1": (.mvmGreenShade1, "#178437"), + "greenShade2": (.mvmGreenShade2, "#0F5B25"), + "orange": (.mvmOrange, "#ED7000"), + "orange66": (.mvmOrange66, "#F3A157"), + "orange33": (.mvmOrange33, "#F9D0AB"), + "orangeShade1": (.mvmOrangeShade1, "#CB5F00"), + "orangeShade2": (.mvmOrangeShade2, "#984700"), + "orangeAA": (.mvmOrangeAA, "#CC4D0F"), + "blue": (.mvmBlue, "#0077B4"), + "blue33": (.mvmBlue33, "#57B1DF"), + "blue66": (.mvmBlue66, "#57B1DF"), + "blueShade1": (.mvmBlueShade1, "#136598"), + "blueShade2": (.mvmBlueShade2, "#0B4467"), "yellow": (.mvmYellow, "#FFBC3D"), + "yellow33": (.mvmYellow33, "#FFE9BF"), + "yellow66": (.mvmYellow66, "#FFD37F"), + "yellowShade1": (.mvmYellowShade1, "#CC9630"), + "yellowShade2": (.mvmYellowShade2, "#997126"), "coolGray1": (.mvmCoolGray1, "#F6F6F6"), "coolGray3": (.mvmCoolGray3, "#D8DADA"), "coolGray6": (.mvmCoolGray6, "#747676"), "coolGray10": (.mvmCoolGray10, "#333333"), - "vzupGold": (.vzupGold, "#B89B56"), - "vzupYellow1": (.vzupYellow1, "#F9D542"), - "vzupYellow2": (.vzupYellow2, "#F4CA53"), - "vzupYellow3": (.vzupYellow3, "#CC9B2D")] + "upGold1": (.vzupGold1, "#F9D542"), + "upGold2": (.vzupGold2, "#F4CA53"), + "upGold3": (.vzupGold3, "#CC9B2D")] //-------------------------------------------------- // MARK: - Brand @@ -41,24 +69,134 @@ extension UIColor { /// HEX: #FFFFFF public static let mvmWhite = UIColor.white + //-------------------------------------------------- + // MARK: - Red + //-------------------------------------------------- + /// HEX: #D52B1E public static let mvmRed = UIColor.color8Bits(red: 213, green: 43, blue: 30) + //-------------------------------------------------- + // MARK: - Pink + //-------------------------------------------------- + + /// HEX: #D90368 + public static let mvmPink = UIColor.color8Bits(red: 217, green: 3, blue: 104) + + /// HEX: #F2ABCD + public static let mvmPink33 = UIColor.color8Bits(red: 242, green: 171, blue: 205) + + /// HEX: #E6589B + public static let mvmPink66 = UIColor.color8Bits(red: 230, green: 88, blue: 155) + + /// HEX: #B31C63 + public static let mvmPinkShade1 = UIColor.color8Bits(red: 179, green: 28, blue: 99) + + /// HEX: #830842 + public static let mvmPinkShade2 = UIColor.color8Bits(red: 131, green: 8, blue: 66) + + //-------------------------------------------------- + // MARK: - Purple + //-------------------------------------------------- + + /// HEX: #8C00AC + public static let mvmPurple = UIColor.color8Bits(red: 140, green: 0, blue: 172) + + /// HEX: #D9ABE4 + public static let mvmPurple33 = UIColor.color8Bits(red: 217, green: 171, blue: 228) + + /// HEX: #B356C8 + public static let mvmPurple66 = UIColor.color8Bits(red: 179, green: 86, blue: 200) + + /// HEX: #6C177F + public static let mvmPurpleShade1 = UIColor.color8Bits(red: 108, green: 23, blue: 127) + + /// HEX: #4A0E58 + public static let mvmPurpleShade2 = UIColor.color8Bits(red: 74, green: 14, blue: 88) + + //-------------------------------------------------- + // MARK: - Orange + //-------------------------------------------------- + + /// HEX: #ED7000 + public static let mvmOrange = UIColor.color8Bits(red: 237, green: 112, blue: 0) + /// HEX: #CC4D0F - public static let mvmOrange = UIColor.color8Bits(red: 204, green: 77, blue: 15) + public static let mvmOrangeAA = UIColor.color8Bits(red: 204, green: 77, blue: 15) - /// HEX: #008631 - public static let mvmGreen = UIColor.color8Bits(red: 0, green: 134, blue: 49) + /// HEX: #F9D0AB + public static let mvmOrange33 = UIColor.color8Bits(red: 249, green: 208, blue: 171) - /// HEX: #007AB8 - public static let mvmBlue = UIColor.color8Bits(red: 0, green: 122, blue: 184) + /// HEX: #F3A157 + public static let mvmOrange66 = UIColor.color8Bits(red: 243, green: 161, blue: 87) - /// HEX: #007AB8 - public static let mvmBlueGradient = UIColor.color8Bits(red: 0, green: 122, blue: 184) + /// HEX: #CB5F00 + public static let mvmOrangeShade1 = UIColor.color8Bits(red: 203, green: 95, blue: 0) + + /// HEX: #984700 + public static let mvmOrangeShade2 = UIColor.color8Bits(red: 152, green: 71, blue: 0) + + //-------------------------------------------------- + // MARK: - Green + //-------------------------------------------------- + + /// HEX: #008330 + public static let mvmGreen = UIColor.color8Bits(red: 0, green: 134, blue: 48) + + /// HEX: #ABE4BF + public static let mvmGreen33 = UIColor.color8Bits(red: 171, green: 228, blue: 191) + + /// HEX: #57C880 + public static let mvmGreen66 = UIColor.color8Bits(red: 87, green: 200, blue: 128) + + /// HEX: #178437 + public static let mvmGreenShade1 = UIColor.color8Bits(red: 23, green: 132, blue: 55) + + /// HEX: #0F5B25 + public static let mvmGreenShade2 = UIColor.color8Bits(red: 15, green: 91, blue: 37) + + //-------------------------------------------------- + // MARK: - Blue + //-------------------------------------------------- + + /// HEX: #0077B4 + public static let mvmBlue = UIColor.color8Bits(red: 0, green: 119, blue: 180) + + /// HEX: #57B1DF + public static let mvmBlue33 = UIColor.color8Bits(red: 87, green: 177, blue: 223) + + /// HEX: #57B1DF + public static let mvmBlue66 = UIColor.color8Bits(red: 87, green: 177, blue: 223) + + /// HEX: #136598 + public static let mvmBlueShade1 = UIColor.color8Bits(red: 19, green: 101, blue: 152) + + /// HEX: #0B4467 + public static let mvmBlueShade2 = UIColor.color8Bits(red: 11, green: 68, blue: 103) + + //-------------------------------------------------- + // MARK: - Yellow + //-------------------------------------------------- /// HEX: #FFBC3D public static let mvmYellow = UIColor.color8Bits(red: 255, green: 188, blue: 61) + /// HEX: #FFE9BF + public static let mvmYellow33 = UIColor.color8Bits(red: 255, green: 233, blue: 191) + + /// HEX: #FFD37F + public static let mvmYellow66 = UIColor.color8Bits(red: 255, green: 211, blue: 127) + + /// HEX: #CC9630 + public static let mvmYellowShade1 = UIColor.color8Bits(red: 204, green: 150, blue: 48) + + /// HEX: #997126 + public static let mvmYellowShade2 = UIColor.color8Bits(red: 153, green: 113, blue: 38) + + //-------------------------------------------------- + // MARK: - Gray + //-------------------------------------------------- + /// HEX: #F6F6F6 public static let mvmCoolGray1 = UIColor.grayscale(rgb: 246) @@ -75,17 +213,14 @@ extension UIColor { // MARK: - VZ UP Brand //-------------------------------------------------- - /// HEX: #B89B56 - public static let vzupGold = UIColor.color8Bits(red: 184, green: 155, blue: 68) - /// HEX: #F9D542 - public static let vzupYellow1 = UIColor.color8Bits(red: 249, green: 213, blue: 66) + public static let vzupGold1 = UIColor.color8Bits(red: 249, green: 213, blue: 66) /// HEX: #F4CA53 - public static let vzupYellow2 = UIColor.color8Bits(red: 244, green: 202, blue: 83) + public static let vzupGold2 = UIColor.color8Bits(red: 244, green: 202, blue: 83) /// HEX: #CC9B2D - public static let vzupYellow3 = UIColor.color8Bits(red: 204, green: 155, blue: 45) + public static let vzupGold3 = UIColor.color8Bits(red: 204, green: 155, blue: 45) //-------------------------------------------------- // MARK: - Functions diff --git a/MVMCoreUI/Categories/UIColor+MFConvenience.h b/MVMCoreUI/Categories/UIColor+MFConvenience.h index 4a51a13b..c3c78c7a 100644 --- a/MVMCoreUI/Categories/UIColor+MFConvenience.h +++ b/MVMCoreUI/Categories/UIColor+MFConvenience.h @@ -21,6 +21,7 @@ + (nonnull UIColor *)mfLightSilver; + (nonnull UIColor *)mfDarkSilver; + (nonnull UIColor *)mfTomatoRed; ++ (nonnull UIColor *)mvmOrange; + (nonnull UIColor *)mfPumpkinColor; + (nonnull UIColor *)mfShamrock; + (nonnull UIColor *)mfCerulean; diff --git a/MVMCoreUI/Categories/UIColor+MFConvenience.m b/MVMCoreUI/Categories/UIColor+MFConvenience.m index e56d89bc..6ff8f70f 100644 --- a/MVMCoreUI/Categories/UIColor+MFConvenience.m +++ b/MVMCoreUI/Categories/UIColor+MFConvenience.m @@ -37,7 +37,6 @@ return [UIColor mfColor8bitsWithRed:198 green:197 blue:197 alpha:1.0]; } - + (nonnull UIColor *)mfPrimaryButtonHighlightBlackColor { return [UIColor mfColor8bitsWithRed:51 green:51 blue:51 alpha:1.0]; } @@ -54,6 +53,10 @@ return [UIColor mfColor8bitsWithRed:204 green:77 blue:15 alpha:1.0]; } ++ (nonnull UIColor *)mvmOrange { + return [UIColor mfColor8bitsWithRed:237 green:112 blue:0 alpha:1.0]; +} + + (nonnull UIColor *)mfShamrock { return [UIColor mfColor8bitsWithRed:0 green:134 blue:49 alpha:1.0]; } diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertView.m b/MVMCoreUI/TopAlert/MVMCoreUITopAlertView.m index 947e6ffc..d0a027b3 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertView.m +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertView.m @@ -108,7 +108,7 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed."; - (nonnull UIColor *)getBackgroundColorForType:(nullable NSString *)type { if ([type isEqualToString:ValueTypeError]) { - return [UIColor mfPumpkinColor]; + return [UIColor mvmOrange]; } else { return [UIColor mfShamrock]; } From cf4832bca7984053da7e029de9857e57444d6d90 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 17 Feb 2020 13:39:13 -0500 Subject: [PATCH 50/57] fixes --- MVMCoreUI/Templates/IsaacLandingTemplate.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/MVMCoreUI/Templates/IsaacLandingTemplate.swift b/MVMCoreUI/Templates/IsaacLandingTemplate.swift index 99c716d6..0001c744 100644 --- a/MVMCoreUI/Templates/IsaacLandingTemplate.swift +++ b/MVMCoreUI/Templates/IsaacLandingTemplate.swift @@ -168,19 +168,19 @@ open class IsaacLandingTemplate: MoleculeListTemplate { let messageStackItem = MoleculeStackItemModel(with: messageLabel) let itemStack = MoleculeStackModel(molecules: [titleStackItem, messageStackItem]) - itemStack.useVerticalMargins = false - itemStack.topMarginPadding = 0 - - itemStack.verticalAlignment = .leading - itemStack.axis = .vertical + itemStack.verticalAlignment = .top itemStack.spacing = 0 - stackItems.append(MoleculeStackItemModel(with: itemStack)) + let horizontalStack = MoleculeStackItemModel(with: itemStack) + horizontalStack.verticalAlignment = .top + stackItems.append(horizontalStack) } + stackItems.first?.percent = 35 + stackItems.last?.percent = 65 let stack = MoleculeStackModel(molecules: stackItems) stack.axis = .horizontal - stack.spacing = 65 + stack.horizontalAlignment = .leading stack.verticalAlignment = .leading let listItem = MoleculeListItemModel(with: stack) From 6de4fc486445b1f0c66557ee520698c458e1fcbe Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 17 Feb 2020 14:19:17 -0500 Subject: [PATCH 51/57] fill color --- MVMCoreUI/BaseClasses/Button.swift | 9 ++++----- MVMCoreUI/Templates/IsaacLandingTemplate.swift | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/MVMCoreUI/BaseClasses/Button.swift b/MVMCoreUI/BaseClasses/Button.swift index 24378184..60e0ab1a 100644 --- a/MVMCoreUI/BaseClasses/Button.swift +++ b/MVMCoreUI/BaseClasses/Button.swift @@ -88,13 +88,12 @@ public typealias ButtonAction = (Button) -> () // MARK:- ModelMoleculeViewProtocol open func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { self.model = model - - guard let model = model as? ButtonModelProtocol else { return } - isEnabled = model.enabled - - if let backgroundColor = (model as? MoleculeModelProtocol)?.backgroundColor { + if let backgroundColor = model?.backgroundColor { self.backgroundColor = backgroundColor.uiColor } + + guard let model = model as? ButtonModelProtocol else { return } + isEnabled = model.enabled set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) } diff --git a/MVMCoreUI/Templates/IsaacLandingTemplate.swift b/MVMCoreUI/Templates/IsaacLandingTemplate.swift index 0001c744..c3d9e9cb 100644 --- a/MVMCoreUI/Templates/IsaacLandingTemplate.swift +++ b/MVMCoreUI/Templates/IsaacLandingTemplate.swift @@ -55,7 +55,7 @@ open class IsaacLandingTemplate: MoleculeListTemplate { if let data = try? JSONSerialization.data(withJSONObject: buttonDict) { let decoder = JSONDecoder() twoButtonModel.primaryButton = try? decoder.decode(ButtonModel.self, from: data) - twoButtonModel.primaryButton?.backgroundColor = Color(uiColor: UIColor.mfGet(forHex: primaryButtonBGColor)) + twoButtonModel.primaryButton?.fillColor = Color(uiColor: UIColor.mfGet(forHex: primaryButtonBGColor)) twoButtonModel.primaryButton?.textColor = Color(uiColor: UIColor.mfGet(forHex: primaryButtonTextColor)) } } @@ -66,7 +66,7 @@ open class IsaacLandingTemplate: MoleculeListTemplate { if let data = try? JSONSerialization.data(withJSONObject: buttonDict) { let decoder = JSONDecoder() twoButtonModel.secondaryButton = try? decoder.decode(ButtonModel.self, from: data) - twoButtonModel.secondaryButton?.backgroundColor = Color(uiColor: UIColor.mfGet(forHex: primaryButtonTextColor)) + twoButtonModel.secondaryButton?.fillColor = Color(uiColor: UIColor.mfGet(forHex: primaryButtonTextColor)) twoButtonModel.secondaryButton?.textColor = Color(uiColor: UIColor.mfGet(forHex:primaryButtonBGColor)) } } From 438661dfe1fe1edf4a4ca4cbbc4f9927021fca9a Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 17 Feb 2020 15:05:02 -0500 Subject: [PATCH 52/57] moleculeName --- MVMCoreUI/Atoms/Buttons/ButtonModel.swift | 6 ++---- MVMCoreUI/Atoms/Views/ImageViewModel.swift | 2 -- MVMCoreUI/Atoms/Views/Label/LabelModel.swift | 4 ---- MVMCoreUI/Molecules/FooterModel.swift | 2 -- .../HorizontalCombinationViews/TwoButtonViewModel.swift | 5 +---- MVMCoreUI/Molecules/Items/MoleculeStackItemModel.swift | 4 +--- .../VerticalCombinationViews/HeadlineBodyModel.swift | 2 -- 7 files changed, 4 insertions(+), 21 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift index 5640996f..2f5e0042 100644 --- a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift @@ -20,7 +20,6 @@ public enum ButtonSize: String, Codable { public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { public static var identifier: String = "button" - public var moleculeName: String? public var backgroundColor: Color? public var title: String public var action: ActionModelProtocol @@ -39,14 +38,14 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { init(with title: String, action: ActionModelProtocol) { self.title = title self.action = action - moleculeName = Self.identifier + //moleculeName = Self.identifier } init(secondaryButtonWith title: String, action: ActionModelProtocol) { self.title = title self.action = action style = .secondary - moleculeName = Self.identifier + //moleculeName = Self.identifier } init(primaryButtonWith title: String, action: ActionModelProtocol) { @@ -75,7 +74,6 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) title = try typeContainer.decode(String.self, forKey: .title) diff --git a/MVMCoreUI/Atoms/Views/ImageViewModel.swift b/MVMCoreUI/Atoms/Views/ImageViewModel.swift index f8443da5..497b0c86 100644 --- a/MVMCoreUI/Atoms/Views/ImageViewModel.swift +++ b/MVMCoreUI/Atoms/Views/ImageViewModel.swift @@ -11,7 +11,6 @@ import Foundation @objcMembers public class ImageViewModel: MoleculeModelProtocol { public static var identifier: String = "image" public var backgroundColor: Color? - public var moleculeName: String? public var image: String public var accessibilityText: String? public var fallbackImage: String? @@ -38,6 +37,5 @@ import Foundation public init(image: String) { self.image = image - moleculeName = Self.identifier } } diff --git a/MVMCoreUI/Atoms/Views/Label/LabelModel.swift b/MVMCoreUI/Atoms/Views/Label/LabelModel.swift index 76597b44..d7fb4fa3 100644 --- a/MVMCoreUI/Atoms/Views/Label/LabelModel.swift +++ b/MVMCoreUI/Atoms/Views/Label/LabelModel.swift @@ -11,9 +11,7 @@ import Foundation @objcMembers public class LabelModel: MoleculeModelProtocol { public static var identifier: String = "label" - public var moleculeName: String? public var backgroundColor: Color? - public var text: String public var accessibilityText: String? public var textColor: String? @@ -48,12 +46,10 @@ import Foundation public init(text: String) { self.text = text - moleculeName = Self.identifier } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName) text = try typeContainer.decode(String.self, forKey: .text) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) textColor = try typeContainer.decodeIfPresent(String.self, forKey: .textColor) diff --git a/MVMCoreUI/Molecules/FooterModel.swift b/MVMCoreUI/Molecules/FooterModel.swift index 57a81f8b..d61d1194 100644 --- a/MVMCoreUI/Molecules/FooterModel.swift +++ b/MVMCoreUI/Molecules/FooterModel.swift @@ -12,7 +12,6 @@ import Foundation @objcMembers public class FooterModel: MoleculeContainerModel, MoleculeModelProtocol { public static var identifier: String = "footer" public var backgroundColor: Color? - public var moleculeName: String? private enum CodingKeys: String, CodingKey { case moleculeName @@ -38,7 +37,6 @@ import Foundation public override init(with moleculeModel: MoleculeModelProtocol) { super.init(with: moleculeModel) setDefaults() - moleculeName = Self.identifier } required public init(from decoder: Decoder) throws { diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift index 70d3f743..4ddb1575 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift @@ -10,7 +10,6 @@ import UIKit public class TwoButtonViewModel: MoleculeModelProtocol { public static var identifier: String = "twoButtonView" - public var moleculeName: String? public var backgroundColor: Color? public var primaryButton: ButtonModel? public var secondaryButton: ButtonModel? @@ -22,9 +21,7 @@ public class TwoButtonViewModel: MoleculeModelProtocol { case secondaryButton } - init() { - moleculeName = Self.identifier - } + init() { } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Molecules/Items/MoleculeStackItemModel.swift b/MVMCoreUI/Molecules/Items/MoleculeStackItemModel.swift index 2b23f405..dc01fd11 100644 --- a/MVMCoreUI/Molecules/Items/MoleculeStackItemModel.swift +++ b/MVMCoreUI/Molecules/Items/MoleculeStackItemModel.swift @@ -13,7 +13,6 @@ import Foundation public var backgroundColor: Color? public var spacing: CGFloat? public var percent: Int? - public var moleculeName: String? public var gone: Bool = false private enum CodingKeys: String, CodingKey { @@ -25,9 +24,8 @@ import Foundation public override init(with moleculeModel: MoleculeModelProtocol) { super.init(with: moleculeModel) - moleculeName = Self.identifier } - + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift index 8d649995..fd5be23a 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift @@ -10,7 +10,6 @@ import Foundation @objcMembers public class HeadlineBodyModel: MoleculeModelProtocol { public static var identifier: String = "headlineBody" - public var moleculeName: String? public var headline: LabelModel? public var body: LabelModel? public var style: String? @@ -18,6 +17,5 @@ import Foundation public init(headline: LabelModel) { self.headline = headline - moleculeName = Self.identifier } } From 79eceb693ebdfa7421228f56216db207b288caa4 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 17 Feb 2020 15:06:33 -0500 Subject: [PATCH 53/57] moleculeName --- MVMCoreUI/Atoms/Buttons/ButtonModel.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift index 2f5e0042..f02eaf5c 100644 --- a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift @@ -38,14 +38,12 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { init(with title: String, action: ActionModelProtocol) { self.title = title self.action = action - //moleculeName = Self.identifier } init(secondaryButtonWith title: String, action: ActionModelProtocol) { self.title = title self.action = action style = .secondary - //moleculeName = Self.identifier } init(primaryButtonWith title: String, action: ActionModelProtocol) { From 347928a9b68b12e3c93e0870b21cdecd5ac8c9de Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 17 Feb 2020 16:48:42 -0500 Subject: [PATCH 54/57] remove files --- MVMCoreUI.xcodeproj/project.pbxproj | 4 - .../MVMCoreUIViewControllerMappingObject.m | 3 +- .../Templates/IsaacLandingTemplate.swift | 194 ------------------ 3 files changed, 1 insertion(+), 200 deletions(-) delete mode 100644 MVMCoreUI/Templates/IsaacLandingTemplate.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 6ac575a6..d114d2ae 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -50,7 +50,6 @@ 0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0198F79E225679870066C936 /* FormValidationProtocol.swift */; }; 0198F7A62256A80B0066C936 /* MFRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 0198F7A02256A80A0066C936 /* MFRadioButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0198F7A22256A80A0066C936 /* MFRadioButton.m */; }; - 01B5E6B023F5F276005B5839 /* IsaacLandingTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01B5E6AF23F5F276005B5839 /* IsaacLandingTemplate.swift */; }; 01C851D323CF9E740021F976 /* LabelToggleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01C851D223CF9E740021F976 /* LabelToggleModel.swift */; }; 01E569D3223FFFA500327251 /* ThreeLayerViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */; }; @@ -383,7 +382,6 @@ 0198F79E225679870066C936 /* FormValidationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidationProtocol.swift; sourceTree = ""; }; 0198F7A02256A80A0066C936 /* MFRadioButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFRadioButton.h; sourceTree = ""; }; 0198F7A22256A80A0066C936 /* MFRadioButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFRadioButton.m; sourceTree = ""; }; - 01B5E6AF23F5F276005B5839 /* IsaacLandingTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IsaacLandingTemplate.swift; sourceTree = ""; }; 01C851D223CF9E740021F976 /* LabelToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelToggleModel.swift; sourceTree = ""; }; 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeModelProtocol.swift; sourceTree = ""; }; 01EB368823609801006832FA /* LabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelModel.swift; sourceTree = ""; }; @@ -1070,7 +1068,6 @@ D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */, 014AA72A23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift */, D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */, - 01B5E6AF23F5F276005B5839 /* IsaacLandingTemplate.swift */, ); path = Templates; sourceTree = ""; @@ -1813,7 +1810,6 @@ D28A839123CD4FD400DFE4FC /* CornerLabelsModel.swift in Sources */, 012A88F123985E0100FE3DA1 /* Color.swift in Sources */, 012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */, - 01B5E6B023F5F276005B5839 /* IsaacLandingTemplate.swift in Sources */, D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */, C003506123AA94CD00B6AC29 /* Button.swift in Sources */, DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */, diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m index fb29096c..5b9592cc 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m @@ -22,8 +22,7 @@ @"stack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackTemplate class]], @"centerMoleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackCenteredTemplate class]], @"list" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeListTemplate class]], - @"threeLayer": [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[ThreeLayerTemplate class]], - @"isaacLanding": [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[IsaacLandingTemplate class]] + @"threeLayer" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[ThreeLayerTemplate class]] } mutableCopy]; }); return viewControllerMapping; diff --git a/MVMCoreUI/Templates/IsaacLandingTemplate.swift b/MVMCoreUI/Templates/IsaacLandingTemplate.swift deleted file mode 100644 index c3d9e9cb..00000000 --- a/MVMCoreUI/Templates/IsaacLandingTemplate.swift +++ /dev/null @@ -1,194 +0,0 @@ -// -// IsaacLandingTemplate.swift -// MVMCoreUI -// -// Created by Suresh, Kamlesh on 2/13/20. -// Copyright © 2020 Verizon Wireless. All rights reserved. -// - -import Foundation - - -open class IsaacLandingTemplate: MoleculeListTemplate { - - func parseTemplateJSON() throws { - - } - - @objc public override func parsePageJSON() throws { - guard let pageJSON = self.loadObject?.pageJSON else { return } - - var listItems: [MoleculeListItemModel] = [] - (pageJSON.arrayForKey("items") as? [[AnyHashable: Any]])?.forEach { (itemJson) in - if let item = getListItem(itemJson) { - listItems.append(item) - } - } - - let template = ListPageTemplateModel(pageType: pageJSON.stringForkey(KeyPageType), - screenHeading: pageJSON.stringForkey(KeyScreenHeading), - molecules: listItems) - - let backgroudColorString = pageJSON.optionalStringForKey("backgroundColor") ?? "#000000" - template.footer = setFooter(pageJSON, template) - //print(template.toJSONString()) - self.templateModel = template - - DispatchQueue.main.async { [weak self] in - self?.view.backgroundColor = UIColor.mfGet(forHex: backgroudColorString) - } - } - - func setFooter(_ pageJSON: [AnyHashable: Any], _ template: ListPageTemplateModel) -> FooterModel? { - - let primaryButtonBGColor = pageJSON.optionalStringForKey("primaryButtonBGColor") ?? "#FFFFFF" - let primaryButtonTextColor = pageJSON.optionalStringForKey("primaryButtonTextColor") ?? "#000000" - - let backgroudColorString = pageJSON.optionalStringForKey("backgroundColor") ?? "#000000" - if let buttonMap = pageJSON.optionalDictionaryForKey("ButtonMap") { - let twoButtonModel = TwoButtonViewModel() - - if let primarybutton = buttonMap.optionalDictionaryForKey(KeyPrimaryButton) { - let buttonDict: [String : Any] = ["title": primarybutton.stringForkey(KeyTitle), - "action": primarybutton, - "moleculeName": "button"] - if let data = try? JSONSerialization.data(withJSONObject: buttonDict) { - let decoder = JSONDecoder() - twoButtonModel.primaryButton = try? decoder.decode(ButtonModel.self, from: data) - twoButtonModel.primaryButton?.fillColor = Color(uiColor: UIColor.mfGet(forHex: primaryButtonBGColor)) - twoButtonModel.primaryButton?.textColor = Color(uiColor: UIColor.mfGet(forHex: primaryButtonTextColor)) - } - } - if let secondaryButton = buttonMap.optionalDictionaryForKey(KeySecondaryButton) { - let buttonDict: [String : Any] = ["title": secondaryButton.stringForkey(KeyTitle), - "action": secondaryButton, - "moleculeName": "button"] - if let data = try? JSONSerialization.data(withJSONObject: buttonDict) { - let decoder = JSONDecoder() - twoButtonModel.secondaryButton = try? decoder.decode(ButtonModel.self, from: data) - twoButtonModel.secondaryButton?.fillColor = Color(uiColor: UIColor.mfGet(forHex: primaryButtonTextColor)) - twoButtonModel.secondaryButton?.textColor = Color(uiColor: UIColor.mfGet(forHex:primaryButtonBGColor)) - } - } - - let footerStack = MoleculeStackModel(molecules: [MoleculeStackItemModel(with:LineModel(type: .standard)), - MoleculeStackItemModel(with: twoButtonModel)]) - footerStack.useHorizontalMargins = false - footerStack.spacing = PaddingFour - - let footer = FooterModel(with: footerStack) - footer.useHorizontalMargins = false - footer.backgroundColor = Color(uiColor: UIColor.mfGet(forHex: backgroudColorString)) - return footer - } - return nil - } - - func getListItem(_ moleculeJson: [AnyHashable: Any]) -> MoleculeListItemModel? { - guard let type = moleculeJson.optionalStringForKey("type") else { - return nil - } - - if type == "rewards" { - return getRewardListItem(moleculeJson) - } else { - return getTitleImageListItem(moleculeJson, type) - } - } - - func getTitleImageListItem(_ moleculeJson: [AnyHashable: Any], _ type: String) -> MoleculeListItemModel? { - let textcolor = moleculeJson.optionalStringForKey("textColor") - var stackItems: [MoleculeStackItemModel] = [] - - let titleLabel = LabelModel(text: moleculeJson.stringForkey(KeyTitle)) - titleLabel.fontName = "NHaasGroteskDSStd-75Bd" - titleLabel.textColor = textcolor - titleLabel.fontSize = (type == "topHeader") ? 70.0 : 25.0 - - let messageLabel = LabelModel(text: moleculeJson.stringForkey("message")) - messageLabel.fontStyle = "B2" - messageLabel.textColor = textcolor - - let headlineBodyModel = HeadlineBodyModel(headline: titleLabel) - headlineBodyModel.body = messageLabel - - if let linkMap = moleculeJson.optionalDictionaryForKey("link") { - do { - let linkDict: [String : Any] = ["title": linkMap.stringForkey(KeyTitle), - "action": linkMap] - let data = try JSONSerialization.data(withJSONObject: linkDict) - let decoder = JSONDecoder() - let linkModel = try decoder.decode(LinkModel.self, from: data) - linkModel.textColor = Color(uiColor: UIColor.mfGet(forHex: textcolor ?? "#FFFFFF")) - let headlineBodyLinkModel = HeadlineBodyLinkModel(headlineBody: headlineBodyModel, - link: linkModel) - stackItems.append(MoleculeStackItemModel(with: headlineBodyLinkModel)) - } catch { - stackItems.append(MoleculeStackItemModel(with: headlineBodyModel)) - } - } else { - stackItems.append(MoleculeStackItemModel(with: headlineBodyModel)) - } - - if let imageurl = moleculeJson.optionalStringForKey("imageUrl") { - let imageModel = ImageViewModel(image: imageurl) - imageModel.height = moleculeJson.optionalCGFloatForKey("imageHeight") ?? 300 - imageModel.imageFormat = "jpeg" - imageModel.contentMode = .scaleAspectFit - stackItems.append(MoleculeStackItemModel(with: imageModel)) - } - - let stack = MoleculeStackModel(molecules: stackItems) - let listItem = MoleculeListItemModel(with: stack) - - let backgroudColorString = moleculeJson.optionalStringForKey("backgroundColor") ?? "#000000" - listItem.backgroundColor = Color(uiColor: UIColor.mfGet(forHex: backgroudColorString)) - listItem.line = LineModel(type: .none) - return listItem - } - - func getRewardListItem(_ moleculeJson: [AnyHashable: Any]) -> MoleculeListItemModel? { - - var stackItems: [MoleculeStackItemModel] = [] - - (moleculeJson.arrayForKey("rewards") as? [[AnyHashable: Any]])?.forEach { (rewardItem) in - let textcolor = rewardItem.optionalStringForKey("textColor") - - let titleLabel = LabelModel(text: rewardItem.stringForkey(KeyTitle)) - titleLabel.fontName = "NHaasGroteskDSStd-75Bd" - titleLabel.textColor = textcolor - titleLabel.fontSize = 48 - - let messageLabel = LabelModel(text: rewardItem.stringForkey("message")) - messageLabel.fontName = "NHaasGroteskDSStd-75Bd" - messageLabel.textColor = textcolor - messageLabel.fontSize = 14 - - let titleStackItem = MoleculeStackItemModel(with: titleLabel) - let messageStackItem = MoleculeStackItemModel(with: messageLabel) - - let itemStack = MoleculeStackModel(molecules: [titleStackItem, messageStackItem]) - itemStack.verticalAlignment = .top - itemStack.spacing = 0 - - let horizontalStack = MoleculeStackItemModel(with: itemStack) - horizontalStack.verticalAlignment = .top - stackItems.append(horizontalStack) - } - - stackItems.first?.percent = 35 - stackItems.last?.percent = 65 - let stack = MoleculeStackModel(molecules: stackItems) - stack.axis = .horizontal - stack.horizontalAlignment = .leading - stack.verticalAlignment = .leading - - let listItem = MoleculeListItemModel(with: stack) - let backgroudColorString = moleculeJson.optionalStringForKey("backgroundColor") ?? "#000000" - listItem.backgroundColor = Color(uiColor: UIColor.mfGet(forHex: backgroudColorString)) - listItem.line = LineModel(type: .none) - - return listItem - } -} - From 68bf45f58310e40b2f96c9bd2a5984fffe5dbff7 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 17 Feb 2020 17:35:20 -0500 Subject: [PATCH 55/57] content mode --- MVMCoreUI.xcodeproj/project.pbxproj | 4 + MVMCoreUI/Atoms/Views/ImageViewModel.swift | 18 +--- MVMCoreUI/Atoms/Views/MFLoadImageView.swift | 48 +-------- .../Categories/UIContentMode+Extension.swift | 98 +++++++++++++++++++ .../TwoButtonViewModel.swift | 5 +- 5 files changed, 109 insertions(+), 64 deletions(-) create mode 100644 MVMCoreUI/Categories/UIContentMode+Extension.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index d114d2ae..03743382 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 012A88F123985E0100FE3DA1 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88F023985E0100FE3DA1 /* Color.swift */; }; 012CA99A2384A687003F810F /* MFTextField+ModelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012CA9992384A687003F810F /* MFTextField+ModelExtension.swift */; }; 012CA99E2385A2D3003F810F /* MFView+ModelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012CA99D2385A2D3003F810F /* MFView+ModelExtension.swift */; }; + 013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */; }; 014AA72423C501E2006F3E93 /* MoleculeContainerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */; }; 014AA72523C501E2006F3E93 /* ContainerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014AA72223C501E2006F3E93 /* ContainerModel.swift */; }; 014AA72623C501E2006F3E93 /* ContainerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014AA72323C501E2006F3E93 /* ContainerModelProtocol.swift */; }; @@ -359,6 +360,7 @@ 012A88F023985E0100FE3DA1 /* Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = ""; }; 012CA9992384A687003F810F /* MFTextField+ModelExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFTextField+ModelExtension.swift"; sourceTree = ""; }; 012CA99D2385A2D3003F810F /* MFView+ModelExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFView+ModelExtension.swift"; sourceTree = ""; }; + 013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIContentMode+Extension.swift"; sourceTree = ""; }; 014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeContainerModel.swift; sourceTree = ""; }; 014AA72223C501E2006F3E93 /* ContainerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContainerModel.swift; sourceTree = ""; }; 014AA72323C501E2006F3E93 /* ContainerModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContainerModelProtocol.swift; sourceTree = ""; }; @@ -1142,6 +1144,7 @@ D29DF11021E6805F003B2FB9 /* Categories */ = { isa = PBXGroup; children = ( + 013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */, D29DF11121E6805F003B2FB9 /* UIColor+MFConvenience.h */, D29DF11321E6805F003B2FB9 /* UIColor+MFConvenience.m */, D29DF11221E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.h */, @@ -1801,6 +1804,7 @@ 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */, D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */, 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */, + 013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */, D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */, D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */, D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */, diff --git a/MVMCoreUI/Atoms/Views/ImageViewModel.swift b/MVMCoreUI/Atoms/Views/ImageViewModel.swift index 497b0c86..97f31ad2 100644 --- a/MVMCoreUI/Atoms/Views/ImageViewModel.swift +++ b/MVMCoreUI/Atoms/Views/ImageViewModel.swift @@ -17,23 +17,7 @@ import Foundation public var imageFormat: String? public var width: CGFloat? public var height: CGFloat? - public var contentMode: ContentMode? - - public enum ContentMode : String, Codable { - case scaleToFill - case scaleAspectFit // contents scaled to fit with fixed aspect. remainder is transparent - case scaleAspectFill // contents scaled to fill with fixed aspect. some portion of content may be clipped. - case redraw // redraw on bounds change (calls -setNeedsDisplay) - case center // contents remain same size. positioned adjusted. - case top - case bottom - case left - case right - case topLeft - case topRight - case bottomLeft - case bottomRight - } + public var contentMode: UIView.ContentMode? public init(image: String) { self.image = image diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift index d46a5150..5e8cedc8 100644 --- a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift @@ -232,54 +232,10 @@ import UIKit imageView.animatedImage = nil loadImage(withName: imageModel.image, format: imageModel.imageFormat, width: width as NSNumber?, height: height as NSNumber?, customFallbackImage: imageModel.fallbackImage) } - setContentMode(imageModel) - } - func setContentMode(_ model: ImageViewModel?) { - switch model?.contentMode { - case .scaleToFill: - imageView.contentMode = .scaleToFill - break - case .scaleAspectFit: - imageView.contentMode = .scaleAspectFit - break - case .scaleAspectFill: - imageView.contentMode = .scaleAspectFill - break - case .redraw: - imageView.contentMode = .redraw - break - case .center: - imageView.contentMode = .center - break - case .top: - imageView.contentMode = .top - break - case .bottom: - imageView.contentMode = .bottom - break - case .left: - imageView.contentMode = .left - break - case .right: - imageView.contentMode = .right - break - case .topLeft: - imageView.contentMode = .topLeft - break - case .topRight: - imageView.contentMode = .topRight - break - case .bottomLeft: - imageView.contentMode = .bottomLeft - break - case .bottomRight: - imageView.contentMode = .bottomRight - break - default: - break + if let contentMode = imageModel.contentMode { + imageView.contentMode = contentMode } - } // MARK: - MVMCoreUIMoleculeViewProtocol functions diff --git a/MVMCoreUI/Categories/UIContentMode+Extension.swift b/MVMCoreUI/Categories/UIContentMode+Extension.swift new file mode 100644 index 00000000..19cf523b --- /dev/null +++ b/MVMCoreUI/Categories/UIContentMode+Extension.swift @@ -0,0 +1,98 @@ +// +// UIContentMode+Extension.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 2/17/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +enum ContentModeError: Error { + case notAContentMode +} + +extension UIView.ContentMode: RawRepresentable { + + init?(rawValue: String) { + switch rawValue { + case "scaleToFill": + self = .scaleToFill + case "scaleAspectFit": + self = .scaleAspectFit + case "scaleAspectFill": + self = .scaleAspectFill + case "redraw": + self = .redraw + case "center": + self = .center + case "top": + self = .top + case "bottom": + self = .bottom + case "left": + self = .left + case "right": + self = .right + case "topLeft": + self = .topLeft + case "topRight": + self = .topRight + case "bottomLeft": + self = .bottomLeft + case "bottomRight": + self = .bottomRight + default: + return nil + } + } + + var rawValueString: String { + switch self { + case .scaleToFill: + return "scaleToFill" + case .scaleAspectFit: + return "scaleAspectFit" + case .scaleAspectFill: + return "scaleAspectFill" + case .redraw: + return "redraw" + case .center: + return "center" + case .top: + return "top" + case .bottom: + return "bottom" + case .left: + return "left" + case .right: + return "right" + case .topLeft: + return "topLeft" + case .topRight: + return "topRight" + case .bottomLeft: + return "bottomLeft" + case .bottomRight: + return "bottomRight" + @unknown default: + return "" + } + } +} + +extension UIView.ContentMode: Codable { + public init(from decoder: Decoder) throws { + let typeContainer = try decoder.singleValueContainer() + let string = try typeContainer.decode(String.self) + guard let mode = UIView.ContentMode(rawValue: string) else { + throw ContentModeError.notAContentMode + } + self = mode + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + try container.encode(rawValueString) + } +} diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift index 4ddb1575..5d608003 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift @@ -21,7 +21,10 @@ public class TwoButtonViewModel: MoleculeModelProtocol { case secondaryButton } - init() { } + init(_ primaryButton: ButtonModel?, _ secondaryButton: ButtonModel?) { + self.primaryButton = primaryButton + self.secondaryButton = secondaryButton + } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) From 3e14e395421d48ade87845b8d32842dd22e8684d Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 17 Feb 2020 17:37:46 -0500 Subject: [PATCH 56/57] public --- .../HorizontalCombinationViews/TwoButtonViewModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift index 5d608003..057203e9 100644 --- a/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift +++ b/MVMCoreUI/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift @@ -21,7 +21,7 @@ public class TwoButtonViewModel: MoleculeModelProtocol { case secondaryButton } - init(_ primaryButton: ButtonModel?, _ secondaryButton: ButtonModel?) { + public init(_ primaryButton: ButtonModel?, _ secondaryButton: ButtonModel?) { self.primaryButton = primaryButton self.secondaryButton = secondaryButton } From 9211d6c86d7c771d1f79453b147d264ca0d3d98e Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 17 Feb 2020 17:44:12 -0500 Subject: [PATCH 57/57] public --- MVMCoreUI/CustomPrimitives/Color.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/CustomPrimitives/Color.swift b/MVMCoreUI/CustomPrimitives/Color.swift index a34fbd45..165fa8ad 100644 --- a/MVMCoreUI/CustomPrimitives/Color.swift +++ b/MVMCoreUI/CustomPrimitives/Color.swift @@ -49,7 +49,7 @@ public final class Color: Codable { // MARK: - Class Initializers //-------------------------------------------------- - init(uiColor: UIColor) { + public init(uiColor: UIColor) { self.uiColor = uiColor hex = UIColor.hexString(for: uiColor) ?? "" determineRGBA()