diff --git a/MVMCoreUI/Models/Molecules/HeaderModel.swift b/MVMCoreUI/Models/Molecules/HeaderModel.swift index 0dca783c..b907b353 100644 --- a/MVMCoreUI/Models/Molecules/HeaderModel.swift +++ b/MVMCoreUI/Models/Molecules/HeaderModel.swift @@ -15,27 +15,34 @@ import Foundation public var molecule: MoleculeProtocol? public var seperator: MoleculeProtocol? - public init(molecule: MoleculeProtocol?){ + public init(molecule: MoleculeProtocol?, backgroundColor: String?, seperator: MoleculeProtocol?){ self.molecule = molecule self.moleculeName = Self.identifier + self.backgroundColor = backgroundColor + self.seperator = seperator } enum CodingKeys: String, CodingKey { case moleculeName case molecule + case backgroundColor case separator } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) self.moleculeName = try typeContainer.decode(String.self, forKey: .moleculeName) + self.backgroundColor = try typeContainer.decode(String.self, forKey: .backgroundColor) self.molecule = try typeContainer.decodeIfPresent(codingKey: .molecule) + self.seperator = try typeContainer.decodeIfPresent(codingKey: .separator) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(self.molecule, forKey: .molecule) + try container.encode(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(self.seperator, forKey: .separator) } } diff --git a/MVMCoreUI/Models/Molecules/LabelModel.swift b/MVMCoreUI/Models/Molecules/LabelModel.swift index 0886524a..859627d5 100644 --- a/MVMCoreUI/Models/Molecules/LabelModel.swift +++ b/MVMCoreUI/Models/Molecules/LabelModel.swift @@ -11,5 +11,7 @@ import Foundation @objcMembers public class LabelModel: MoleculeProtocol { public static var identifier: String = "label" + public var moleculeName: String? public var text: String? + public var spacing: Int? } diff --git a/MVMCoreUI/Models/Molecules/MoleculeStackItemModel.swift b/MVMCoreUI/Models/Molecules/MoleculeStackItemModel.swift index 9c75b582..ea01c844 100644 --- a/MVMCoreUI/Models/Molecules/MoleculeStackItemModel.swift +++ b/MVMCoreUI/Models/Molecules/MoleculeStackItemModel.swift @@ -17,7 +17,7 @@ import Foundation public var percentage: Int? public var verticalAlignment: String? public var horizontalAlignment: String? - public var gone = false + public var gone: Bool? = false public init(molecule: MoleculeProtocol?, spacing: CGFloat?, percentage: Int?, verticalAlignment: String?, horizontalAlignment: String?, gone: Bool = false) { self.molecule = molecule @@ -44,11 +44,11 @@ import Foundation self.moleculeName = try typeContainer.decode(String.self, forKey: .moleculeName) self.molecule = try typeContainer.decodeIfPresent(codingKey: .molecule) - self.spacing = try typeContainer.decode(CGFloat.self, forKey: .spacing) - self.percentage = try typeContainer.decode(Int.self, forKey: .percentage) - self.verticalAlignment = try typeContainer.decode(String.self, forKey: .verticalAlignment) - self.horizontalAlignment = try typeContainer.decode(String.self, forKey: .horizontalAlignment) - self.gone = try typeContainer.decode(Bool.self, forKey: .gone) + self.spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing) + self.percentage = try typeContainer.decodeIfPresent(Int.self, forKey: .percentage) + self.verticalAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .verticalAlignment) + self.horizontalAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .horizontalAlignment) + self.gone = try typeContainer.decodeIfPresent(Bool.self, forKey: .gone) } public func encode(to encoder: Encoder) throws { diff --git a/MVMCoreUI/Models/Molecules/MoleculeStackModel.swift b/MVMCoreUI/Models/Molecules/MoleculeStackModel.swift index bad35824..088a2733 100644 --- a/MVMCoreUI/Models/Molecules/MoleculeStackModel.swift +++ b/MVMCoreUI/Models/Molecules/MoleculeStackModel.swift @@ -32,8 +32,8 @@ 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.molecules = try typeContainer.decode([MoleculeStackItemModel].self, forKey: .molecules) + self.moleculeName = try typeContainer.decode(String.self, forKey: .moleculeName) + self.molecules = try typeContainer.decodeIfPresent([MoleculeStackItemModel].self, forKey: .molecules) self.axis = try typeContainer.decodeIfPresent(String.self, forKey: .axis) self.spacing = try typeContainer.decodeIfPresent(Float.self, forKey: .spacing) } diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift index a7d96a34..c9f2299f 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift @@ -44,13 +44,13 @@ import UIKit open override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) eyebrow.setWithJSON(json?.optionalDictionaryForKey("eyebrow"), delegateObject: delegateObject, additionalData: additionalData) - stack.items[0].gone = !eyebrow.hasText + stack.stackItems[0].gone = !eyebrow.hasText headline.setWithJSON(json?.optionalDictionaryForKey("headline"), delegateObject: delegateObject, additionalData: additionalData) - stack.items[1].gone = !headline.hasText + stack.stackItems[1].gone = !headline.hasText body.setWithJSON(json?.optionalDictionaryForKey("body"), delegateObject: delegateObject, additionalData: additionalData) - stack.items[2].gone = !body.hasText + stack.stackItems[2].gone = !body.hasText link.setWithJSON(json?.optionalDictionaryForKey("link"), delegateObject: delegateObject, additionalData: additionalData) - stack.items[3].gone = link.titleLabel?.text?.count ?? 0 == 0 + stack.stackItems[3].gone = link.titleLabel?.text?.count ?? 0 == 0 stack.restack() } diff --git a/MVMCoreUI/Organisms/MoleculeStackView.swift b/MVMCoreUI/Organisms/MoleculeStackView.swift index c47ca142..fd6896e4 100644 --- a/MVMCoreUI/Organisms/MoleculeStackView.swift +++ b/MVMCoreUI/Organisms/MoleculeStackView.swift @@ -45,7 +45,7 @@ public class StackItem { public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol { var contentView: UIView = MVMCoreUICommonViewsUtility.commonView() - var items: [StackItem] = [] + var stackItems: [StackItem] = [] var useStackSpacingBeforeFirstItem = false var moleculeStackModel: MoleculeStackModel? @@ -88,12 +88,12 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol /// Restacks the existing items. func restack() { - setWithStackItems(items) + setWithStackItems(stackItems) } /// Removes all stack items views from the view. func removeAllItemViews() { - for item in items { + for item in stackItems { item.view.removeFromSuperview() } } @@ -130,7 +130,7 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol public override func updateView(_ size: CGFloat) { super.updateView(size) - for item in items { + for item in stackItems { (item.view as? MVMCoreViewProtocol)?.updateView(size) } } @@ -140,7 +140,7 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol super.reset() backgroundColor = .clear updateViewHorizontalDefaults = true - for item in items { + for item in stackItems { if let view = item.view as? MVMCoreUIMoleculeViewProtocol { view.reset?() } @@ -163,10 +163,15 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol // If the items in the stack are the same, just update previous items instead of re-allocating. var items: [StackItem]? - if MoleculeStackView.name(forReuse: previousModel, delegateObject: delegateObject) == MoleculeStackView.name(forReuse: model, delegateObject: delegateObject) { - items = self.items + if let previousModel = previousModel { + let previoudReuseName = MoleculeStackView.name(forReuse: previousModel, delegateObject: delegateObject) + let currentReuseName = MoleculeStackView.name(forReuse: model, delegateObject: delegateObject) + if previoudReuseName == currentReuseName { + items = self.stackItems + } } - self.items = [] + + self.stackItems = [] guard let molecules = model.molecules else { return @@ -176,15 +181,15 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol //setAxisWithJSON(json) spacing = CGFloat(model.spacing ?? 16) - for (index, moleculeContainer) in molecules.enumerated() { - if let stackItemModel = moleculeContainer.molecule as? MoleculeStackItemModel { + for (index, stackItemModel) in molecules.enumerated() { + if let moleculeModel = stackItemModel.molecule { var view: UIView? if let item = items?[index] { item.update(with: stackItemModel) view = item.view - (view as? ModelMoleculeViewProtocol)?.setWithModel(stackItemModel, delegateObject, nil) + (view as? ModelMoleculeViewProtocol)?.setWithModel(moleculeModel, delegateObject, nil) addStackItem(item, lastItem: index == molecules.count - 1) - } else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(stackItemModel, delegateObject, true) { + } else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(moleculeModel, delegateObject, true) { view = moleculeView addStackItem(StackItem(with: moleculeView, stackItemModel: stackItemModel), lastItem: index == molecules.count - 1) } @@ -254,7 +259,7 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol /// Adds the stack item to the stack. func addStackItem(_ stackItem: StackItem, lastItem: Bool) { guard !stackItem.gone else { - items.append(stackItem) + stackItems.append(stackItem) return } let view = stackItem.view @@ -268,11 +273,11 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol view.alignHorizontal?(horizontalAlignment) view.alignVertical?(verticalAlignment) } - let first = items.first { !$0.gone } == nil + let first = stackItems.first { !$0.gone } == nil if axis == .vertical { if first { pinView(view, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: useStackSpacingBeforeFirstItem ? spacing : stackItem.spacing ?? 0) - } else if let previousView = items.last(where: { stackItem in + } else if let previousView = stackItems.last(where: { stackItem in return !stackItem.gone })?.view { _ = NSLayoutConstraint(pinFirstView: previousView, toSecondView: view, withConstant: spacing, directionVertical: true) @@ -289,7 +294,7 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol if first { // First horizontal item has no spacing by default unless told otherwise. pinView(view, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: useStackSpacingBeforeFirstItem ? spacing : stackItem.spacing ?? 0) - } else if let previousView = items.last(where: { stackItem in + } else if let previousView = stackItems.last(where: { stackItem in return !stackItem.gone })?.view { _ = NSLayoutConstraint(pinFirstView: previousView, toSecondView: view, withConstant: spacing, directionVertical: false) @@ -303,12 +308,12 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol if lastItem { pinView(contentView, toView: view, attribute: .right, relation: .equal, priority: .required, constant: 0) } - items.append(stackItem) + stackItems.append(stackItem) } func setWithStackItems(_ items: [StackItem]) { removeAllItemViews() - self.items.removeAll() + self.stackItems.removeAll() var previousPresentItem: StackItem? = nil for item in items { if !item.gone {