From ee66dbe8d59bf0b06bfd486bbf83de095e675748 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 21 Feb 2020 09:27:30 -0500 Subject: [PATCH 1/8] Caret fix in table view cell code condensing extra init functions --- MVMCoreUI/Atoms/Buttons/ButtonModel.swift | 2 +- MVMCoreUI/Atoms/Buttons/CaretLinkModel.swift | 2 +- MVMCoreUI/Atoms/Views/Checkbox.swift | 2 +- MVMCoreUI/Atoms/Views/CheckboxModel.swift | 2 + .../Atoms/Views/CircleProgressModel.swift | 5 +- MVMCoreUI/BaseClasses/TableViewCell.swift | 14 ++--- .../Views/Container/ContainerModel.swift | 6 +++ ...tLeftVariableCheckboxAllTextAndLinks.swift | 30 +++-------- ...VariableCheckboxAllTextAndLinksModel.swift | 2 +- .../ListLeftVariableIconWithRightCaret.swift | 38 +++++-------- ...tLeftVariableIconWithRightCaretModel.swift | 3 +- .../List/RightVariable/ListRVWheel.swift | 29 +++------- .../List/RightVariable/ListRVWheelModel.swift | 8 ++- .../ListRightVariablePayments.swift | 40 +++++--------- .../ListRightVariablePaymentsModel.swift | 6 +++ .../ListThreeColumnPlanDataDivider.swift | 30 +++-------- .../ListThreeColumnPlanDataDividerModel.swift | 3 ++ .../Molecules/Items/StackItemModel.swift | 13 ++--- .../EyebrowHeadlineBodyLinkModel.swift | 54 ++++++++++++++++++- MVMCoreUI/Organisms/StackModel.swift | 3 +- 20 files changed, 149 insertions(+), 143 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift index f02eaf5c..917f573d 100644 --- a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift @@ -24,7 +24,7 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { public var title: String public var action: ActionModelProtocol public var enabled: Bool = true - public var style: ButtonStyle? + public var style: ButtonStyle? = .primary public var size: ButtonSize? = .standard public var fillColor: Color? public var textColor: Color? diff --git a/MVMCoreUI/Atoms/Buttons/CaretLinkModel.swift b/MVMCoreUI/Atoms/Buttons/CaretLinkModel.swift index 4b28fc8c..4ea79ef8 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretLinkModel.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretLinkModel.swift @@ -15,7 +15,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { public var title: String public var action: ActionModelProtocol public var enabledColor: Color = Color(uiColor: .black) - public var disabledColor: Color? = Color(uiColor: .mfSilver()) + public var disabledColor: Color? = Color(uiColor: .mvmCoolGray6) public var enabled = true public init(title: String, action: ActionModelProtocol) { diff --git a/MVMCoreUI/Atoms/Views/Checkbox.swift b/MVMCoreUI/Atoms/Views/Checkbox.swift index 27bed31e..2980b879 100644 --- a/MVMCoreUI/Atoms/Views/Checkbox.swift +++ b/MVMCoreUI/Atoms/Views/Checkbox.swift @@ -395,7 +395,7 @@ import MVMCore heightConstraint?.constant = dimension } - layoutIfNeeded() + //layoutIfNeeded() } public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { diff --git a/MVMCoreUI/Atoms/Views/CheckboxModel.swift b/MVMCoreUI/Atoms/Views/CheckboxModel.swift index de79c6c6..706597ff 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxModel.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxModel.swift @@ -58,6 +58,8 @@ import Foundation case isEnabled case action } + + init(isChecked: Bool = false) {} //-------------------------------------------------- // MARK: - Codec diff --git a/MVMCoreUI/Atoms/Views/CircleProgressModel.swift b/MVMCoreUI/Atoms/Views/CircleProgressModel.swift index 3cafb1bb..2fc67b44 100644 --- a/MVMCoreUI/Atoms/Views/CircleProgressModel.swift +++ b/MVMCoreUI/Atoms/Views/CircleProgressModel.swift @@ -37,7 +37,10 @@ public class CircleProgressModel: MoleculeModelProtocol { public var colors = [Color]() public var backgroundColor: Color? - public init() {} + public init() { + updateStyle() + updateSize() + } private enum CodingKeys: String, CodingKey { case style diff --git a/MVMCoreUI/BaseClasses/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift index fe06a05a..ac91f292 100644 --- a/MVMCoreUI/BaseClasses/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -198,16 +198,16 @@ import UIKit /// Adds the standard mvm style caret to the accessory view @objc public func addCaretViewAccessory() { guard accessoryView == nil else { return } - caretView = CaretView(lineWidth: 1) - caretView?.translatesAutoresizingMaskIntoConstraints = true - caretView?.size = .small(.vertical) - caretView?.setConstraints() - - if let size = caretView?.size?.dimensions() { + let caret = CaretView(lineWidth: 1) + caret.translatesAutoresizingMaskIntoConstraints = true + caret.size = .small(.vertical) + if let size = caret.size?.dimensions() { + caret.frame = CGRect(origin: CGPoint.zero, size: size) caretViewWidthSizeObject = MFSizeObject(standardSize: size.width, standardiPadPortraitSize: 9) caretViewHeightSizeObject = MFSizeObject(standardSize: size.height, standardiPadPortraitSize: 16) } - accessoryView = caretView + caretView = caret + accessoryView = caret } /// NOTE: Should only be called when displayed or about to be displayed. diff --git a/MVMCoreUI/Containers/Views/Container/ContainerModel.swift b/MVMCoreUI/Containers/Views/Container/ContainerModel.swift index cdc6d743..a5e89adb 100644 --- a/MVMCoreUI/Containers/Views/Container/ContainerModel.swift +++ b/MVMCoreUI/Containers/Views/Container/ContainerModel.swift @@ -27,6 +27,12 @@ public class ContainerModel: ContainerModelProtocol, Codable { } public init() {} + + public convenience init(horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil) { + self.init() + self.horizontalAlignment = horizontalAlignment + self.verticalAlignment = verticalAlignment + } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift index 553e6359..0dad7228 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift @@ -8,49 +8,33 @@ import Foundation -@objcMembers public class ListLeftVariableCheckboxAllTextAndLinks: TableViewCell { +@objcMembers open class ListLeftVariableCheckboxAllTextAndLinks: TableViewCell { public let checkbox = Checkbox(frame: .zero) public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) public let stack = Stack(frame: .zero) // MARK: - View Lifecycle - open override func updateView(_ size: CGFloat) { - super.updateView(size) - stack.updateView(size) - } - override open func setupView() { super.setupView() stack.stackItems = [StackItem(andContain: checkbox),StackItem(andContain: eyebrowHeadlineBodyLink)] - contentView.addSubview(stack) - containerHelper.constrainView(stack) - } - - // MARK:- ModelMoleculeViewProtocol - override open func reset() { - super.reset() - stack.reset() + addMolecule(stack) } // MARK:- MVMCoreUIMoleculeViewProtocol - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.setWithModel(model, delegateObject, additionalData) guard let model = model as? ListLeftVariableCheckboxAllTextAndLinksModel else { return} checkbox.setWithModel(model.checkbox, delegateObject, additionalData) eyebrowHeadlineBodyLink.setWithModel(model.eyebrowHeadlineBodyLink, delegateObject, additionalData) - // Create a stack model to use for the internal stack and set the alignment of labels - let checkbox = StackItemModel() - checkbox.horizontalAlignment = .fill - let eyebrowHeadlineBodyLink = StackItemModel() - eyebrowHeadlineBodyLink.horizontalAlignment = .leading - let stackModel = StackModel(molecules: [checkbox,eyebrowHeadlineBodyLink]) - stackModel.axis = .horizontal + let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .fill), + StackItemModel(horizontalAlignment: .leading)], + axis: .horizontal) stack.model = stackModel stack.restack() } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 140 } } diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinksModel.swift b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinksModel.swift index 2fb89b1e..fec71c0b 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinksModel.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinksModel.swift @@ -28,7 +28,7 @@ public class ListLeftVariableCheckboxAllTextAndLinksModel: ListItemModel, Molecu required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink) - checkbox = try typeContainer.decode(CheckboxModel.self, forKey: .checkbox) + checkbox = try typeContainer.decodeIfPresent(CheckboxModel.self, forKey: .checkbox) ?? CheckboxModel() try super.init(from: decoder) } diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift index 9f0e2deb..058d0da3 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaret.swift @@ -9,7 +9,7 @@ import Foundation import UIKit -@objcMembers public class ListLeftVariableIconWithRightCaret: TableViewCell { +@objcMembers open class ListLeftVariableIconWithRightCaret: TableViewCell { //----------------------------------------------------- // MARK: - Outlets @@ -22,17 +22,11 @@ import UIKit //----------------------------------------------------- // MARK: - View Lifecycle //------------------------------------------------------- - open override func updateView(_ size: CGFloat) { - super.updateView(size) - stack.updateView(size) - } override open func setupView() { super.setupView() - stack.translatesAutoresizingMaskIntoConstraints = false stack.stackItems = [StackItem(andContain: leftImage),StackItem(andContain: leftLabel),StackItem(andContain: rightLabel)] - contentView.addSubview(stack) - containerHelper.constrainView(stack) + addMolecule(stack) leftLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 901), for: .horizontal) rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 902), for: .horizontal) } @@ -40,32 +34,28 @@ import UIKit //---------------------------------------------------- // MARK: - Molecule //------------------------------------------------------ - override open func reset() { - super.reset() - stack.reset() - } - - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.setWithModel(model, delegateObject, additionalData) 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) - // 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 + let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .fill), + StackItemModel(horizontalAlignment: .fill), + StackItemModel(horizontalAlignment: .trailing)], + axis: .horizontal) stack.model = stackModel stack.restack() } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 90 } + + open override func reset() { + super.reset() + leftLabel.styleB2(true) + rightLabel.styleB2(true) + } } diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretModel.swift b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretModel.swift index bccf5320..4b426909 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretModel.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretModel.swift @@ -19,6 +19,7 @@ public class ListLeftVariableIconWithRightCaretModel: ListItemModel, MoleculeMod if image.height == nil { image.height = 30.0 } + rightLabel.hero = 0 } public init(image: ImageViewModel, leftLabel: LabelModel, rightLabel: LabelModel) { @@ -43,7 +44,7 @@ public class ListLeftVariableIconWithRightCaretModel: ListItemModel, MoleculeMod try super.init(from: decoder) } - public override 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(moleculeName, forKey: .moleculeName) diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRVWheel.swift b/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRVWheel.swift index e9e09639..46d4b955 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRVWheel.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRVWheel.swift @@ -13,46 +13,30 @@ import Foundation let rightLabel = Label.commonLabelB2(true) let stack = Stack(frame: .zero) - //------------------------------------------------- - // MARK: - View Cycle - //------------------------------------------------- - open override func updateView(_ size: CGFloat) { - super.updateView(size) - stack.updateView(size) - } - //------------------------------------------------- // MARK: - Setup //------------------------------------------------- open override func setupView() { super.setupView() rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal) - stack.translatesAutoresizingMaskIntoConstraints = false stack.stackItems = [StackItem(andContain: leftLabel),StackItem(andContain: wheel),StackItem(andContain: rightLabel)] - contentView.addSubview(stack) - containerHelper.constrainView(stack) + addMolecule(stack) } //------------------------------------------------- // MARK: - ModelMoleculeViewProtocol //------------------------------------------------- - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.setWithModel(model, delegateObject, additionalData) guard let model = model as? ListRVWheelModel else { return } leftLabel.setWithModel(model.leftLabel, delegateObject, additionalData) rightLabel.setWithModel(model.rightLabel, delegateObject, additionalData) wheel.setWithModel(model.wheel, delegateObject, additionalData) - // Create a stack model to use for the internal stack and set the alignment of models - let leftLabelStackItem = StackItemModel() - leftLabelStackItem.horizontalAlignment = .leading - let wheelStackItem = StackItemModel() - wheelStackItem.horizontalAlignment = .fill - let rightLabelStackItem = StackItemModel() - rightLabelStackItem.horizontalAlignment = .fill - rightLabelStackItem.spacing = 4 - let stackModel = StackModel(molecules: [leftLabelStackItem,wheelStackItem,rightLabelStackItem]) - stackModel.axis = .horizontal + let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .leading), + StackItemModel(horizontalAlignment: .fill), + StackItemModel(spacing: 4, horizontalAlignment: .fill)], + axis: .horizontal) stack.model = stackModel stack.restack() } @@ -62,7 +46,6 @@ import Foundation //------------------------------------------------- open override func reset() { super.reset() - stack.reset() leftLabel.styleB1(true) rightLabel.styleB2(true) } diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRVWheelModel.swift b/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRVWheelModel.swift index 3831f5c7..89b70b0f 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRVWheelModel.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRVWheelModel.swift @@ -20,6 +20,12 @@ public class ListRVWheelModel: ListItemModel, MoleculeModelProtocol { super.init() } + /// Defaults to set + override public func setDefaults() { + super.setDefaults() + rightLabel.hero = 0 + } + private enum CodingKeys: String, CodingKey { case moleculeName case leftLabel @@ -31,7 +37,7 @@ public class ListRVWheelModel: ListItemModel, MoleculeModelProtocol { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel) rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) - wheel = try typeContainer.decode(CircleProgressModel.self, forKey: .wheel) + wheel = try typeContainer.decodeIfPresent(CircleProgressModel.self, forKey: .wheel) ?? CircleProgressModel() try super.init(from: decoder) } diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePayments.swift b/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePayments.swift index 2bfbc321..66f88371 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePayments.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePayments.swift @@ -8,12 +8,11 @@ import Foundation -@objcMembers public class ListRightVariablePayments: TableViewCell { +@objcMembers open class ListRightVariablePayments: TableViewCell { //----------------------------------------------------- // MARK: - Outlets //------------------------------------------------------- - let leftLabel = Label.commonLabelB1(true) let rightImage = MFLoadImageView(pinnedEdges: .all) let stack = Stack(frame: .zero) @@ -21,49 +20,34 @@ import Foundation //----------------------------------------------------- // MARK: - View Lifecycle //------------------------------------------------------- - - open override func updateView(_ size: CGFloat) { - super.updateView(size) - stack.updateView(size) - } - override open func setupView() { super.setupView() - guard leftLabel.superview == nil else { - return - } - stack.translatesAutoresizingMaskIntoConstraints = false stack.stackItems = [StackItem(andContain: leftLabel),StackItem(andContain: rightImage)] - contentView.addSubview(stack) - containerHelper.constrainView(stack) + addMolecule(stack) } //---------------------------------------------------- // MARK: - Molecule //------------------------------------------------------ - override open func reset() { - super.reset() - stack.reset() - } - - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.setWithModel(model, delegateObject, additionalData) guard let model = model as? ListRightVariablePaymentsModel else { return } leftLabel.setWithModel(model.leftLabel, delegateObject, additionalData) rightImage.setWithModel(model.image, delegateObject, additionalData) - // Create a stack model to use for the internal stack and set the alignment of label and image - let leftLabel = StackItemModel() - leftLabel.horizontalAlignment = .leading - let rightImage = StackItemModel() - rightImage.horizontalAlignment = .fill - let stackModel = StackModel(molecules: [leftLabel,rightImage]) - stackModel.axis = .horizontal + let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .leading), + StackItemModel(horizontalAlignment: .fill)], + axis: .horizontal) stack.model = stackModel stack.restack() } - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 65 } + + open override func reset() { + super.reset() + leftLabel.styleB1(true) + } } diff --git a/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePaymentsModel.swift b/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePaymentsModel.swift index a8c6ff80..4842b60a 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePaymentsModel.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePaymentsModel.swift @@ -20,6 +20,12 @@ public class ListRightVariablePaymentsModel: ListItemModel, MoleculeModelProtoco super.init() } + /// Defaults to set + override public func setDefaults() { + super.setDefaults() + leftLabel.hero = 0 + } + static func createPayPalImage() -> ImageViewModel { let image = ImageViewModel(image: "imageName_PayPal_logo") image.localBundle = MVMCoreUIUtility.bundleForMVMCoreUI() diff --git a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift index 19774110..565ed737 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift @@ -16,23 +16,16 @@ import Foundation let stack = Stack(frame: .zero) // MARK: - MFViewProtocol - open override func updateView(_ size: CGFloat) { - super.updateView(size) - stack.updateView(size) - } - open override func setupView() { super.setupView() //using stackItems to align the three headlineBody - stack.translatesAutoresizingMaskIntoConstraints = false stack.stackItems = [StackItem(andContain: leftHeadlineBody),StackItem(andContain: centerHeadLineBody),StackItem(andContain: rightHeadLineBody)] - contentView.addSubview(stack) - containerHelper.constrainView(stack) + addMolecule(stack) } // MARK: - MVMCoreUIMoleculeViewProtocol - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + open 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) @@ -40,24 +33,15 @@ import Foundation rightHeadLineBody.setWithModel(model.rightHeadlineBody, delegateObject, additionalData) // 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 + let stackModel = StackModel(molecules: [StackItemModel(percent: 33, horizontalAlignment: .leading), + StackItemModel(percent: 34, horizontalAlignment: .center), + StackItemModel(percent: 33, horizontalAlignment: .trailing)], + axis: .horizontal) stack.model = stackModel stack.restack() } - open override func reset() { - super.reset() - stack.reset() - } - - public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { return 121 } } diff --git a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDividerModel.swift b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDividerModel.swift index fd946eb0..3ddfe64b 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDividerModel.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDividerModel.swift @@ -26,6 +26,9 @@ public class ListThreeColumnPlanDataDividerModel: ListItemModel, MoleculeModelPr override public func setDefaults() { super.setDefaults() style = "tallDivider" + leftHeadlineBody.style = "itemHeader" + centerHeadlineBody.style = "itemHeader" + rightHeadlineBody.style = "itemHeader" } private enum CodingKeys: String, CodingKey { diff --git a/MVMCoreUI/Molecules/Items/StackItemModel.swift b/MVMCoreUI/Molecules/Items/StackItemModel.swift index b7d1a269..795b2983 100644 --- a/MVMCoreUI/Molecules/Items/StackItemModel.swift +++ b/MVMCoreUI/Molecules/Items/StackItemModel.swift @@ -16,13 +16,14 @@ import Foundation public var percent: Int? public var gone: Bool = false - public convenience init(gone: Bool) { - self.init() - self.gone = gone - } - - public convenience init(percent: Int) { + public convenience init(spacing: CGFloat? = nil, percent: Int? = nil, horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil, gone: Bool? = nil) { self.init() + self.horizontalAlignment = horizontalAlignment + self.verticalAlignment = verticalAlignment + self.spacing = spacing self.percent = percent + if let gone = gone { + self.gone = gone + } } } diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift index 913933d9..2ff3ca57 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift @@ -8,7 +8,7 @@ import Foundation -public struct EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol { +public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol { public static var identifier: String = "eyebrowHeadlineBodyLink" public var moleculeName: String? = EyebrowHeadlineBodyLinkModel.identifier public var backgroundColor: Color? @@ -16,4 +16,56 @@ public struct EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol { public var headline: LabelModel? public var body: LabelModel? public var link: LinkModel? + + public init(eyebrow: LabelModel? = nil, headline: LabelModel? = nil, body: LabelModel? = nil, link: LinkModel? = nil) throws { + // TODO: This class initializers should ensure that atleast one item is set. + /*guard eyebrow != nil || headline != nil || body != nil || link != nil else { + throw + }*/ + self.eyebrow = eyebrow + self.headline = headline + self.body = body + self.link = link + setDefaults() + } + + /// Defaults to set + public func setDefaults() { + if let headline = headline { + headline.hero = 0 + } + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case backgroundColor + case eyebrow + case headline + case body + case link + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow) + headline = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .headline) + body = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body) + link = try typeContainer.decodeIfPresent(LinkModel.self, forKey: .link) + setDefaults() + // TODO: This class initializers should ensure that atleast one item is set. + /*guard eyebrow != nil || headline != nil || body != nil || link != nil else { + throw + }*/ + } + + 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(eyebrow, forKey: .eyebrow) + try container.encodeIfPresent(headline, forKey: .headline) + try container.encodeIfPresent(body, forKey: .body) + try container.encodeIfPresent(link, forKey: .link) + } } diff --git a/MVMCoreUI/Organisms/StackModel.swift b/MVMCoreUI/Organisms/StackModel.swift index 8d670efb..b762a03c 100644 --- a/MVMCoreUI/Organisms/StackModel.swift +++ b/MVMCoreUI/Organisms/StackModel.swift @@ -16,8 +16,9 @@ import Foundation public var spacing: CGFloat = 16.0 public var useStackSpacingBeforeFirstItem = false - public init(molecules: [StackItemModel]) { + public init(molecules: [StackItemModel], axis: NSLayoutConstraint.Axis = .vertical) { self.molecules = molecules + self.axis = axis } private enum CodingKeys: String, CodingKey { From dedcd9de12a9d02dcaf3da414e6a78bf4bcf3f2b Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 21 Feb 2020 10:16:00 -0500 Subject: [PATCH 2/8] undo commented code --- MVMCoreUI/Atoms/Views/Checkbox.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atoms/Views/Checkbox.swift b/MVMCoreUI/Atoms/Views/Checkbox.swift index 2980b879..27bed31e 100644 --- a/MVMCoreUI/Atoms/Views/Checkbox.swift +++ b/MVMCoreUI/Atoms/Views/Checkbox.swift @@ -395,7 +395,7 @@ import MVMCore heightConstraint?.constant = dimension } - //layoutIfNeeded() + layoutIfNeeded() } public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { From 17583c107ce721dab4a044d76add9fc61eae3e38 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 21 Feb 2020 14:31:46 -0500 Subject: [PATCH 3/8] moved hero is setWithModel. Was not being set. Mild changes. --- MVMCoreUI/Atoms/Views/Label/Label.swift | 3 ++- MVMCoreUI/Atoms/Views/Label/LabelModel.swift | 20 +++++++++++++-- MVMCoreUI/BaseClasses/TableViewCell.swift | 6 ++--- .../EyebrowHeadlineBodyLink.swift | 14 ++++++++--- MVMCoreUI/Organisms/Stack.swift | 25 ++++++++----------- 5 files changed, 44 insertions(+), 24 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atoms/Views/Label/Label.swift index 013f7f11..b300b7bb 100644 --- a/MVMCoreUI/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label/Label.swift @@ -231,6 +231,7 @@ public typealias ActionBlock = () -> () attributedText = nil originalAttributedString = nil text = labelModel.text + hero = labelModel.hero Label.setLabel(self, withHTML: labelModel.html) let alignment = LabelAlignment(rawValue: labelModel.textAlignment ?? "") @@ -344,7 +345,6 @@ public typealias ActionBlock = () -> () } attributedText = attributedString originalAttributedString = attributedText - hero = labelModel.hero } } @@ -716,6 +716,7 @@ extension Label { public func reset() { text = nil attributedText = nil + hero = nil textAlignment = .left originalAttributedString = nil styleB2(true) diff --git a/MVMCoreUI/Atoms/Views/Label/LabelModel.swift b/MVMCoreUI/Atoms/Views/Label/LabelModel.swift index d7fb4fa3..cb9cc0a9 100644 --- a/MVMCoreUI/Atoms/Views/Label/LabelModel.swift +++ b/MVMCoreUI/Atoms/Views/Label/LabelModel.swift @@ -10,6 +10,10 @@ import Foundation @objcMembers public class LabelModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "label" public var backgroundColor: Color? public var text: String @@ -24,6 +28,10 @@ import Foundation public var hero: Int? public var makeWholeViewClickable: Bool? + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case text @@ -43,11 +51,19 @@ import Foundation enum AttributeTypeKey: String, CodingKey { case type } - + + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(text: String) { self.text = text } - + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) text = try typeContainer.decode(String.self, forKey: .text) diff --git a/MVMCoreUI/BaseClasses/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift index ac91f292..a301926c 100644 --- a/MVMCoreUI/BaseClasses/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -198,8 +198,8 @@ import UIKit /// Adds the standard mvm style caret to the accessory view @objc public func addCaretViewAccessory() { guard accessoryView == nil else { return } + let caret = CaretView(lineWidth: 1) - caret.translatesAutoresizingMaskIntoConstraints = true caret.size = .small(.vertical) if let size = caret.size?.dimensions() { caret.frame = CGRect(origin: CGPoint.zero, size: size) @@ -217,11 +217,11 @@ import UIKit layoutIfNeeded() guard let heroLabel = findHeroLabel(views: contentView.subviews), let hero = heroLabel.hero else { return } let rect = Label.boundingRect(forCharacterRange: NSRange(location: hero, length: 1), in: heroLabel) - accessoryView?.center.y = contentView.convert(UIView(frame: rect).center, from: heroLabel).y + accessoryView?.center.y = convert(UIView(frame: rect).center, from: heroLabel).y heroAccessoryCenter = accessoryView?.center } - /// Traverses the view hierarchy for a 🦸‍♂️heroic Label. + /// Traverses the view hierarchy for a 🦸‍♂️ heroic Label. private func findHeroLabel(views: [UIView]) -> Label? { if views.isEmpty { diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift index 8f206e35..c964c6ed 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift @@ -9,11 +9,13 @@ import UIKit @objcMembers open class EyebrowHeadlineBodyLink: Container { + let stack = Stack(frame: .zero) let eyebrow = Label.commonLabelB3(true) let headline = Label.commonLabelB1(true) let body = Label.commonLabelB2(true) let link = Link() + var casteModel: EyebrowHeadlineBodyLinkModel? { get { return model as? EyebrowHeadlineBodyLinkModel } } @@ -21,7 +23,10 @@ import UIKit // MARK: - MFViewProtocol open override func setupView() { super.setupView() - stack.stackItems = [StackItem(andContain: eyebrow),StackItem(andContain: headline),StackItem(andContain: body),StackItem(andContain: link)] + stack.stackItems = [StackItem(andContain: eyebrow), + StackItem(andContain: headline), + StackItem(andContain: body), + StackItem(andContain: link)] addSubview(stack) NSLayoutConstraint.constraintPinSubview(toSuperview: stack) } @@ -42,7 +47,7 @@ import UIKit } // MARK:- ModelMoleculeViewProtocol - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.setWithModel(model, delegateObject, additionalData) eyebrow.setWithModel(casteModel?.eyebrow, delegateObject, additionalData) headline.setWithModel(casteModel?.headline, delegateObject, additionalData) @@ -50,7 +55,10 @@ import UIKit link.setWithModel(casteModel?.link, delegateObject, additionalData) // Create a stack model to use for the internal stack. - let stackModel = StackModel(molecules: [StackItemModel(gone: !eyebrow.hasText),StackItemModel(gone: !headline.hasText),StackItemModel(gone: !body.hasText),StackItemModel(gone: (link.titleLabel?.text?.count ?? 0) == 0)]) + let stackModel = StackModel(molecules: [StackItemModel(gone: !eyebrow.hasText), + StackItemModel(gone: !headline.hasText), + StackItemModel(gone: !body.hasText), + StackItemModel(gone: (link.titleLabel?.text?.count ?? 0) == 0)]) stackModel.spacing = 0 stack.model = stackModel stack.restack() diff --git a/MVMCoreUI/Organisms/Stack.swift b/MVMCoreUI/Organisms/Stack.swift index 4e7a3114..1f2fa288 100644 --- a/MVMCoreUI/Organisms/Stack.swift +++ b/MVMCoreUI/Organisms/Stack.swift @@ -51,7 +51,7 @@ open class Stack: Container where T: StackModelProtocol { super.init(frame: frame) } - public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { super.init(frame: CGRect.zero) setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) } @@ -63,9 +63,7 @@ open class Stack: Container where T: StackModelProtocol { // MARK: - MFViewProtocol public override func setupView() { super.setupView() - guard contentView.superview == nil else { - return - } + guard contentView.superview == nil else { return } MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0) translatesAutoresizingMaskIntoConstraints = false backgroundColor = .clear @@ -91,7 +89,7 @@ open class Stack: Container where T: StackModelProtocol { } } - public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { let previousModel = self.model super.setWithModel(model, delegateObject, additionalData) removeAllItemViews() @@ -132,6 +130,7 @@ open class Stack: Container where T: StackModelProtocol { guard let model = molecule as? T else { return 0 } let horizontal = model.axis == .horizontal var estimatedHeight: CGFloat = 0 + for case let item in model.molecules { if item.gone { continue } let height = (MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(item) as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(forRow: item, delegateObject: delegateObject) ?? 0 @@ -161,11 +160,10 @@ open class Stack: Container where T: StackModelProtocol { // MARK: - Subclassables /// Can be subclassed to create views when we get stack item models and have no views yet - func createStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - } + func createStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { } /// Can be subclassed to set stack items with model when we already have views - func setStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + func setStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let models = stackModel?.molecules else { return } for (index, element) in models.enumerated() { (stackItems[index] as? ModelMoleculeViewProtocol)?.setWithModel(element, delegateObject, additionalData) @@ -178,6 +176,7 @@ open class Stack: Container where T: StackModelProtocol { guard let stackModel = stackModel else { return 0.0 } var totalSpace: CGFloat = 0.0 var firstMoleculeFound = false + for stackItemModel in stackModel.molecules { guard !stackItemModel.gone else { continue } let spacing = stackItemModel.spacing ?? stackModel.spacing @@ -214,9 +213,7 @@ open class Stack: Container where T: StackModelProtocol { if stackModel.axis == .vertical { if first { pinView(view, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: stackModel.useStackSpacingBeforeFirstItem ? spacing : model.spacing ?? 0) - } else if let previousView = stackItems.last(where: { item in - return !model.gone - }) { + } else if let previousView = stackItems.last(where: { item in !model.gone }) { view.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: spacing).isActive = true } pinView(view, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: 0) @@ -233,15 +230,13 @@ open class Stack: Container where T: StackModelProtocol { if first { // First horizontal item has no spacing by default unless told otherwise. pinView(view, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: stackModel.useStackSpacingBeforeFirstItem ? spacing : model.spacing ?? 0) - } else if let previousView = stackItems.last(where: { item in - return !model.gone - }) { + } else if let previousView = stackItems.last(where: { item in !model.gone }) { view.leftAnchor.constraint(equalTo: previousView.rightAnchor, constant: spacing).isActive = true } pinView(view, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: 0) pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0) if let percent = model.percent { - let multiplier = CGFloat(percent)/100.0 + let multiplier = CGFloat(percent) / 100.0 let constant = multiplier * totalSpacing view.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: multiplier, constant: -constant).isActive = true } From 0c11ded57778570e316f981f16a4ac4f4361d567 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 21 Feb 2020 14:41:53 -0500 Subject: [PATCH 4/8] rolled back change. --- MVMCoreUI/Organisms/Stack.swift | 35 ++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Organisms/Stack.swift b/MVMCoreUI/Organisms/Stack.swift index 1f2fa288..67ff0110 100644 --- a/MVMCoreUI/Organisms/Stack.swift +++ b/MVMCoreUI/Organisms/Stack.swift @@ -9,13 +9,20 @@ import Foundation open class Stack: Container where T: StackModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + var contentView: UIView = MVMCoreUICommonViewsUtility.commonView() var stackModel: T? { get { return model as? T } } var stackItems: [UIView] = [] + //-------------------------------------------------- // MARK: - Helpers + //-------------------------------------------------- + public func pinView(_ view: UIView, toView: UIView, attribute: NSLayoutConstraint.Attribute, relation: NSLayoutConstraint.Relation, priority: UILayoutPriority, constant: CGFloat) { let constraint = NSLayoutConstraint(item: view, attribute: attribute, relatedBy: relation, toItem: toView, attribute: attribute, multiplier: 1.0, constant: constant) constraint.priority = priority @@ -45,8 +52,11 @@ open class Stack: Container where T: StackModelProtocol { item.removeFromSuperview() } } + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- - // MARK: - Inits public override init(frame: CGRect) { super.init(frame: frame) } @@ -60,7 +70,10 @@ open class Stack: Container where T: StackModelProtocol { fatalError("init(coder:) has not been implemented") } + //-------------------------------------------------- // MARK: - MFViewProtocol + //-------------------------------------------------- + public override func setupView() { super.setupView() guard contentView.superview == nil else { return } @@ -80,7 +93,10 @@ open class Stack: Container where T: StackModelProtocol { } } + //-------------------------------------------------- // MARK: - MVMCoreUIMoleculeViewProtocol + //-------------------------------------------------- + public override func reset() { super.reset() backgroundColor = .clear @@ -157,8 +173,10 @@ open class Stack: Container where T: StackModelProtocol { return modules.count > 0 ? modules : nil } + //-------------------------------------------------- // MARK: - Subclassables - + //-------------------------------------------------- + /// Can be subclassed to create views when we get stack item models and have no views yet func createStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { } @@ -170,7 +188,10 @@ open class Stack: Container where T: StackModelProtocol { } } + //-------------------------------------------------- // MARK: - Adding to stack + //-------------------------------------------------- + /// Gets the percent modifier. This value is used to help properly calculate percent for stack items when spacing is involved. private func getTotalSpace() -> CGFloat { guard let stackModel = stackModel else { return 0.0 } @@ -213,13 +234,15 @@ open class Stack: Container where T: StackModelProtocol { if stackModel.axis == .vertical { if first { pinView(view, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: stackModel.useStackSpacingBeforeFirstItem ? spacing : model.spacing ?? 0) - } else if let previousView = stackItems.last(where: { item in !model.gone }) { + } else if let previousView = stackItems.last(where: { item in + return !model.gone + }) { view.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: spacing).isActive = true } pinView(view, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: 0) pinView(contentView, toView: view, attribute: .trailing, relation: .equal, priority: .required, constant: 0) if let percent = model.percent { - let multiplier = CGFloat(percent)/100.0 + let multiplier = CGFloat(percent) / 100.0 let constant = multiplier * totalSpacing view.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: multiplier, constant: -constant).isActive = true } @@ -230,7 +253,9 @@ open class Stack: Container where T: StackModelProtocol { if first { // First horizontal item has no spacing by default unless told otherwise. pinView(view, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: stackModel.useStackSpacingBeforeFirstItem ? spacing : model.spacing ?? 0) - } else if let previousView = stackItems.last(where: { item in !model.gone }) { + } else if let previousView = stackItems.last(where: { item in + return !model.gone + }) { view.leftAnchor.constraint(equalTo: previousView.rightAnchor, constant: spacing).isActive = true } pinView(view, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: 0) From f8895157097676ce1ce3e4e41363f2f85544c87b Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Sun, 23 Feb 2020 13:34:20 -0500 Subject: [PATCH 5/8] hero is working. commenting done. --- .../EyebrowHeadlineBodyLink.swift | 15 +++++++++- .../EyebrowHeadlineBodyLinkModel.swift | 28 ++++++++++++++++--- MVMCoreUI/Organisms/Stack.swift | 2 ++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift index c964c6ed..e9d7d34e 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift @@ -9,6 +9,9 @@ import UIKit @objcMembers open class EyebrowHeadlineBodyLink: Container { + //-------------------------------------------------- + // MARK: - Outlets + //-------------------------------------------------- let stack = Stack(frame: .zero) let eyebrow = Label.commonLabelB3(true) @@ -20,7 +23,10 @@ import UIKit get { return model as? EyebrowHeadlineBodyLinkModel } } + //-------------------------------------------------- // MARK: - MFViewProtocol + //-------------------------------------------------- + open override func setupView() { super.setupView() stack.stackItems = [StackItem(andContain: eyebrow), @@ -36,7 +42,10 @@ import UIKit stack.updateView(size) } + //-------------------------------------------------- // MARK: - MVMCoreUIMoleculeViewProtocol + //-------------------------------------------------- + open override func reset() { super.reset() stack.reset() @@ -46,9 +55,13 @@ import UIKit body.styleB2(true) } - // MARK:- ModelMoleculeViewProtocol + //-------------------------------------------------- + // MARK: - ModelMoleculeViewProtocol + //-------------------------------------------------- + open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.setWithModel(model, delegateObject, additionalData) + eyebrow.setWithModel(casteModel?.eyebrow, delegateObject, additionalData) headline.setWithModel(casteModel?.headline, delegateObject, additionalData) body.setWithModel(casteModel?.body, delegateObject, additionalData) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift index 2ff3ca57..e277f5de 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift @@ -9,6 +9,10 @@ import Foundation public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "eyebrowHeadlineBodyLink" public var moleculeName: String? = EyebrowHeadlineBodyLinkModel.identifier public var backgroundColor: Color? @@ -17,11 +21,15 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol { public var body: LabelModel? public var link: LinkModel? + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(eyebrow: LabelModel? = nil, headline: LabelModel? = nil, body: LabelModel? = nil, link: LinkModel? = nil) throws { // TODO: This class initializers should ensure that atleast one item is set. /*guard eyebrow != nil || headline != nil || body != nil || link != nil else { - throw - }*/ + throw + }*/ self.eyebrow = eyebrow self.headline = headline self.body = body @@ -29,6 +37,10 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol { setDefaults() } + //-------------------------------------------------- + // MARK: - Method + //-------------------------------------------------- + /// Defaults to set public func setDefaults() { if let headline = headline { @@ -36,6 +48,10 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol { } } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor @@ -45,6 +61,10 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol { case link } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) @@ -55,8 +75,8 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol { setDefaults() // TODO: This class initializers should ensure that atleast one item is set. /*guard eyebrow != nil || headline != nil || body != nil || link != nil else { - throw - }*/ + throw + }*/ } public func encode(to encoder: Encoder) throws { diff --git a/MVMCoreUI/Organisms/Stack.swift b/MVMCoreUI/Organisms/Stack.swift index 67ff0110..602ab0f1 100644 --- a/MVMCoreUI/Organisms/Stack.swift +++ b/MVMCoreUI/Organisms/Stack.swift @@ -8,6 +8,7 @@ import Foundation + open class Stack: Container where T: StackModelProtocol { //-------------------------------------------------- // MARK: - Properties @@ -24,6 +25,7 @@ open class Stack: Container where T: StackModelProtocol { //-------------------------------------------------- public func pinView(_ view: UIView, toView: UIView, attribute: NSLayoutConstraint.Attribute, relation: NSLayoutConstraint.Relation, priority: UILayoutPriority, constant: CGFloat) { + let constraint = NSLayoutConstraint(item: view, attribute: attribute, relatedBy: relation, toItem: toView, attribute: attribute, multiplier: 1.0, constant: constant) constraint.priority = priority constraint.isActive = true From e33fe346c69bd3e0a748a4d2f51d6e5917fe96fd Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 24 Feb 2020 09:58:47 -0500 Subject: [PATCH 6/8] mild updates --- MVMCoreUI/Atoms/Views/Label/Label.swift | 3 --- MVMCoreUI/BaseClasses/TableViewCell.swift | 7 ++----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atoms/Views/Label/Label.swift index b300b7bb..f08d532d 100644 --- a/MVMCoreUI/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label/Label.swift @@ -808,9 +808,6 @@ extension Label { - Attention: This method expects text to be set first. Otherwise, it will do nothing. - parameter range: The range of text to be tapped. - - parameter actionMap: - - parameter delegate: - - parameter additionalData: */ @objc public func addTappableLinkAttribute(range: NSRange, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) { diff --git a/MVMCoreUI/BaseClasses/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift index a301926c..8547457e 100644 --- a/MVMCoreUI/BaseClasses/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -139,7 +139,6 @@ import UIKit topSeparatorView?.updateView(size) bottomSeparatorView?.updateView(size) - molecule?.updateView(size) } @@ -153,9 +152,7 @@ import UIKit //TODO: Model, Change to model public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - guard let model = model as? ListItemModelProtocol else { - return - } + guard let model = model as? ListItemModelProtocol else { return } self.listItemModel = model style(with: model.style) @@ -194,7 +191,7 @@ import UIKit return nil } - // MARK: - Arrow + // MARK: - Caret View /// Adds the standard mvm style caret to the accessory view @objc public func addCaretViewAccessory() { guard accessoryView == nil else { return } From 9b5379626607dab86fbca95d8b8d4fab72ab7ff9 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 24 Feb 2020 10:13:45 -0500 Subject: [PATCH 7/8] undoing removal --- MVMCoreUI/BaseClasses/TableViewCell.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCoreUI/BaseClasses/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift index 8547457e..d96a4587 100644 --- a/MVMCoreUI/BaseClasses/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -197,6 +197,7 @@ import UIKit guard accessoryView == nil else { return } let caret = CaretView(lineWidth: 1) + caret.translatesAutoresizingMaskIntoConstraints = true caret.size = .small(.vertical) if let size = caret.size?.dimensions() { caret.frame = CGRect(origin: CGPoint.zero, size: size) From b255b1acac35b5c41b41bbb6ba2699335c7a74b7 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 24 Feb 2020 16:53:42 -0500 Subject: [PATCH 8/8] header updates --- MVMCoreUI.xcodeproj/project.pbxproj | 16 +++++-- MVMCoreUI/Atoms/Buttons/ButtonModel.swift | 2 +- .../Containers/Views/MoleculeContainer.swift | 8 ++-- .../Views/MoleculeContainerModel.swift | 2 +- .../Views/MoleculeContainerProtocol.swift | 13 ++++++ MVMCoreUI/Molecules/HeaderModel.swift | 20 ++++---- MVMCoreUI/Molecules/MoleculeHeaderModel.swift | 37 +++++++++++++++ ...derView.swift => MoleculeHeaderView.swift} | 46 +++++++------------ .../OtherHandlers/MoleculeObjectMapping.swift | 2 +- 9 files changed, 95 insertions(+), 51 deletions(-) create mode 100644 MVMCoreUI/Containers/Views/MoleculeContainerProtocol.swift create mode 100644 MVMCoreUI/Molecules/MoleculeHeaderModel.swift rename MVMCoreUI/Molecules/{HeaderView.swift => MoleculeHeaderView.swift} (60%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 4afd3a24..3e9138f7 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -307,7 +307,7 @@ D2A5145F2211DDC100345BFB /* MoleculeStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5145E2211DDC100345BFB /* MoleculeStackView.swift */; }; D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */; }; D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */; }; - D2A514672213885800345BFB /* HeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A514662213885800345BFB /* HeaderView.swift */; }; + D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A514662213885800345BFB /* MoleculeHeaderView.swift */; }; D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; }; D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A638FC22CA98280052ED1F /* HeadlineBody.swift */; }; D2A6390122CBB1820052ED1F /* Carousel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A6390022CBB1820052ED1F /* Carousel.swift */; }; @@ -322,6 +322,8 @@ 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 */; }; + D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D90B41240463E100DD6EC9 /* MoleculeHeaderModel.swift */; }; + D2D90B442404789000DD6EC9 /* MoleculeContainerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D90B432404789000DD6EC9 /* MoleculeContainerProtocol.swift */; }; D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */; }; D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */; }; D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */; }; @@ -650,7 +652,7 @@ D2A5145E2211DDC100345BFB /* MoleculeStackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackView.swift; sourceTree = ""; }; D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackTemplate.swift; sourceTree = ""; }; D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackCenteredTemplate.swift; sourceTree = ""; }; - D2A514662213885800345BFB /* HeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderView.swift; sourceTree = ""; }; + D2A514662213885800345BFB /* MoleculeHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeHeaderView.swift; sourceTree = ""; }; D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerViewController.swift; sourceTree = ""; }; D2A638FC22CA98280052ED1F /* HeadlineBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBody.swift; sourceTree = ""; }; D2A6390022CBB1820052ED1F /* Carousel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Carousel.swift; sourceTree = ""; }; @@ -665,6 +667,8 @@ 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 = ""; }; + D2D90B41240463E100DD6EC9 /* MoleculeHeaderModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeHeaderModel.swift; sourceTree = ""; }; + D2D90B432404789000DD6EC9 /* MoleculeContainerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeContainerProtocol.swift; sourceTree = ""; }; D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUIDelegateObject.swift; sourceTree = ""; }; D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerTableViewController.swift; sourceTree = ""; }; D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeListTemplate.swift; sourceTree = ""; }; @@ -757,6 +761,7 @@ children = ( 9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */, D29E28DE23D740FC00ACEA85 /* Container */, + D2D90B432404789000DD6EC9 /* MoleculeContainerProtocol.swift */, 014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */, D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */, ); @@ -1128,7 +1133,8 @@ D224798E2316A995003FCCF9 /* HorizontalCombinationViews */, D224798D2316A988003FCCF9 /* VerticalCombinationViews */, 01EB368C23609801006832FA /* HeaderModel.swift */, - D2A514662213885800345BFB /* HeaderView.swift */, + D2D90B41240463E100DD6EC9 /* MoleculeHeaderModel.swift */, + D2A514662213885800345BFB /* MoleculeHeaderView.swift */, 012A88EB238F084D00FE3DA1 /* FooterModel.swift */, D274CA322236A78900B01B62 /* FooterView.swift */, 0116A4E4228B19640094F3ED /* RadioButtonModel.swift */, @@ -1716,7 +1722,7 @@ D2E2A99C23D8D975000B42E6 /* ImageHeadlineBodyModel.swift in Sources */, D28A837F23CCA96400DFE4FC /* TabsModel.swift in Sources */, 012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */, - D2A514672213885800345BFB /* HeaderView.swift in Sources */, + D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */, D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */, 01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */, D28A838323CCBD3F00DFE4FC /* CircleProgressModel.swift in Sources */, @@ -1781,6 +1787,7 @@ D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, 8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */, D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */, + D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */, 012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */, D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */, 9445890E2385C3F800DE9FD4 /* MultiProgressModel.swift in Sources */, @@ -1802,6 +1809,7 @@ D22D1F47220496A30077CEC0 /* MVMCoreUISwitch.m in Sources */, C695A67F23C9830600BFB94E /* UnOrderedListModel.swift in Sources */, 017BEB4223620AD20024EF95 /* FormModelProtocol.swift in Sources */, + D2D90B442404789000DD6EC9 /* MoleculeContainerProtocol.swift in Sources */, 012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */, D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */, 0AE14F64238315D2005417F8 /* TextField.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift index 917f573d..f02eaf5c 100644 --- a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift @@ -24,7 +24,7 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { public var title: String public var action: ActionModelProtocol public var enabled: Bool = true - public var style: ButtonStyle? = .primary + public var style: ButtonStyle? public var size: ButtonSize? = .standard public var fillColor: Color? public var textColor: Color? diff --git a/MVMCoreUI/Containers/Views/MoleculeContainer.swift b/MVMCoreUI/Containers/Views/MoleculeContainer.swift index 9a907222..d179ef72 100644 --- a/MVMCoreUI/Containers/Views/MoleculeContainer.swift +++ b/MVMCoreUI/Containers/Views/MoleculeContainer.swift @@ -31,7 +31,7 @@ open class MoleculeContainer: Container { } public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - if let casteModel = model as? MoleculeContainerModel { + if let casteModel = model as? MoleculeContainerModelProtocol { if view != nil { (view as? ModelMoleculeViewProtocol)?.setWithModel(casteModel.molecule, delegateObject, additionalData) } else { @@ -44,7 +44,7 @@ open class MoleculeContainer: Container { } public override static func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { - guard let containerModel = model as? MoleculeContainerModel, + guard let containerModel = model as? MoleculeContainerModelProtocol, let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(containerModel.molecule) as? ModelMoleculeViewProtocol.Type, let moleculeName = moleculeClass.nameForReuse(containerModel.molecule, delegateObject) else { return "\(model?.moleculeName ?? "moleculeContainer")<>" @@ -53,7 +53,7 @@ open class MoleculeContainer: Container { } public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - guard let containerModel = molecule as? MoleculeContainerModel else { return 0 } + guard let containerModel = molecule as? MoleculeContainerModelProtocol else { return 0 } guard let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(containerModel.molecule) as? ModelMoleculeViewProtocol.Type, let moleculeHeight = moleculeClass.estimatedHeight(forRow: containerModel.molecule, delegateObject: delegateObject) else { return (containerModel.topMarginPadding ?? 0) + (containerModel.bottomMarginPadding ?? 0) @@ -62,7 +62,7 @@ open class MoleculeContainer: Container { } public override class func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { - guard let containerModel = molecule as? MoleculeContainerModel, + guard let containerModel = molecule as? MoleculeContainerModelProtocol, let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(containerModel.molecule) as? ModelMoleculeViewProtocol.Type else { return nil } return moleculeClass.requiredModules(containerModel.molecule, delegateObject: delegateObject, error: error) } diff --git a/MVMCoreUI/Containers/Views/MoleculeContainerModel.swift b/MVMCoreUI/Containers/Views/MoleculeContainerModel.swift index 0421b3d1..95683f8f 100644 --- a/MVMCoreUI/Containers/Views/MoleculeContainerModel.swift +++ b/MVMCoreUI/Containers/Views/MoleculeContainerModel.swift @@ -8,7 +8,7 @@ import Foundation -public class MoleculeContainerModel: ContainerModel { +public class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProtocol { public var molecule: MoleculeModelProtocol private enum CodingKeys: String, CodingKey { diff --git a/MVMCoreUI/Containers/Views/MoleculeContainerProtocol.swift b/MVMCoreUI/Containers/Views/MoleculeContainerProtocol.swift new file mode 100644 index 00000000..882cf181 --- /dev/null +++ b/MVMCoreUI/Containers/Views/MoleculeContainerProtocol.swift @@ -0,0 +1,13 @@ +// +// MoleculeContainerProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 2/24/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol MoleculeContainerModelProtocol: ContainerModelProtocol { + var molecule: MoleculeModelProtocol { get set } +} diff --git a/MVMCoreUI/Molecules/HeaderModel.swift b/MVMCoreUI/Molecules/HeaderModel.swift index b6f3629f..6314947c 100644 --- a/MVMCoreUI/Molecules/HeaderModel.swift +++ b/MVMCoreUI/Molecules/HeaderModel.swift @@ -8,19 +8,17 @@ import Foundation -@objcMembers public class HeaderModel: MoleculeContainerModel, MoleculeModelProtocol { - public static var identifier: String = "header" +@objcMembers public class HeaderModel: ContainerModel { public var backgroundColor: Color? public var line: LineModel? private enum CodingKeys: String, CodingKey { - case moleculeName case line case backgroundColor } /// Defaults to set - func setDefaults() { + public func setDefaults() { if useHorizontalMargins == nil { useHorizontalMargins = true } @@ -33,25 +31,27 @@ import Foundation if bottomMarginPadding == nil { bottomMarginPadding = PaddingDefaultVerticalSpacing } - line?.type = .heavy + if line == nil { + line = LineModel(type: .heavy) + } } - public override init(with moleculeModel: MoleculeModelProtocol) { - super.init(with: moleculeModel) + public override init() { + super.init() setDefaults() } required public init(from decoder: Decoder) throws { try super.init(from: decoder) - setDefaults() let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) ?? LineModel(type: .heavy) + line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + setDefaults() } 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(line, forKey: .line) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) } diff --git a/MVMCoreUI/Molecules/MoleculeHeaderModel.swift b/MVMCoreUI/Molecules/MoleculeHeaderModel.swift new file mode 100644 index 00000000..92958ca1 --- /dev/null +++ b/MVMCoreUI/Molecules/MoleculeHeaderModel.swift @@ -0,0 +1,37 @@ +// +// MoleculeHeaderModel.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 10/3/19. +// Copyright © 2019 Suresh, Kamlesh. All rights reserved. +// + +import Foundation + +@objcMembers public class MoleculeHeaderModel: HeaderModel, MoleculeModelProtocol, MoleculeContainerModelProtocol { + public static var identifier: String = "header" + 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/HeaderView.swift b/MVMCoreUI/Molecules/MoleculeHeaderView.swift similarity index 60% rename from MVMCoreUI/Molecules/HeaderView.swift rename to MVMCoreUI/Molecules/MoleculeHeaderView.swift index c90be96d..5d58c675 100644 --- a/MVMCoreUI/Molecules/HeaderView.swift +++ b/MVMCoreUI/Molecules/MoleculeHeaderView.swift @@ -1,5 +1,5 @@ // -// HeaderView.swift +// MoleculeHeaderView.swift // MVMCoreUI // // Created by Scott Pfeil on 2/12/19. @@ -8,55 +8,41 @@ import UIKit -public class HeaderView: MoleculeContainer { - var line: Line? +public class MoleculeHeaderView: MoleculeContainer { + var line = Line() - var headerModel: HeaderModel? { - get { return model as? HeaderModel } + var headerModel: MoleculeHeaderModel? { + get { return model as? MoleculeHeaderModel } } // MARK: - MVMCoreViewProtocol open override func updateView(_ size: CGFloat) { super.updateView(size) - line?.updateView(size) + line.updateView(size) } public override func setupView() { super.setupView() - - guard line == nil else { return } - let line = Line() line.setStyle(.heavy) addSubview(line) NSLayoutConstraint.pinViewBottom(toSuperview: line, useMargins: false, constant: 0).isActive = true NSLayoutConstraint.pinViewLeft(toSuperview: line, useMargins: true, constant: 0).isActive = true NSLayoutConstraint.pinViewRight(toSuperview: line, useMargins: true, constant: 0).isActive = true - self.line = line } // MARK: - MVMCoreUIMoleculeViewProtocol - open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - if let separatorJSON = json?.optionalDictionaryForKey("line") { - line?.setWithJSON(separatorJSON, delegateObject: delegateObject, additionalData: additionalData) - } - } - - open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.setWithModel(model, delegateObject, additionalData) - - guard let headerModel = model as? HeaderModel else { - return - } - - if let seperatorModel = headerModel.line { - line?.setWithJSON(seperatorModel.toJSON(), delegateObject: delegateObject, additionalData: additionalData) - } - } - open override func reset() { super.reset() - line?.setStyle(.heavy) + line.setStyle(.heavy) + } + + // MARK: - ModelMoleculeViewProtocol + open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.setWithModel(model, delegateObject, additionalData) + guard let headerModel = headerModel else { return } + if let lineModel = headerModel.line { + line.setWithModel(lineModel, delegateObject, additionalData) + } } public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index 7ae80d49..fde8f4cb 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -88,7 +88,7 @@ import Foundation MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeCollectionViewCell.self, viewModelClass: CarouselItemModel.self) // Other Container Molecules - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeaderView.self, viewModelClass: HeaderModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeHeaderView.self, viewModelClass: MoleculeHeaderModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: FooterView.self, viewModelClass: FooterModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Scroller.self, viewModelClass: ScrollerModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ModuleMolecule.self, viewModelClass: ModuleMoleculeModel.self)