diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 0b07aacf..c6619e3c 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -315,6 +315,8 @@ D282AACB2243C61700C46919 /* ButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AACA2243C61700C46919 /* ButtonView.swift */; }; D28764AA2458980300CB882D /* ThreeLayerFillMiddleTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28764A92458980300CB882D /* ThreeLayerFillMiddleTemplate.swift */; }; D28764AC245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28764AB245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift */; }; + D28764F9245A327200CB882D /* TwoLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28764F8245A327200CB882D /* TwoLinkView.swift */; }; + D28764FB245A33A500CB882D /* TwoLinkViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28764FA245A33A500CB882D /* TwoLinkViewModel.swift */; }; D28A837923C7D5BC00DFE4FC /* PageModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837823C7D5BC00DFE4FC /* PageModelProtocol.swift */; }; D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837A23C928DA00DFE4FC /* MoleculeListCellProtocol.swift */; }; D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837C23CCA86A00DFE4FC /* TabsListItemModel.swift */; }; @@ -774,6 +776,8 @@ D282AACA2243C61700C46919 /* ButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonView.swift; sourceTree = ""; }; D28764A92458980300CB882D /* ThreeLayerFillMiddleTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerFillMiddleTemplate.swift; sourceTree = ""; }; D28764AB245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerFillMiddleTemplateModel.swift; sourceTree = ""; }; + D28764F8245A327200CB882D /* TwoLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoLinkView.swift; sourceTree = ""; }; + D28764FA245A33A500CB882D /* TwoLinkViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoLinkViewModel.swift; sourceTree = ""; }; D28A837823C7D5BC00DFE4FC /* PageModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageModelProtocol.swift; sourceTree = ""; }; D28A837A23C928DA00DFE4FC /* MoleculeListCellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeListCellProtocol.swift; sourceTree = ""; }; D28A837C23CCA86A00DFE4FC /* TabsListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsListItemModel.swift; sourceTree = ""; }; @@ -1351,6 +1355,8 @@ 94F6516C2437954100631BF9 /* Tabs.swift */, 011D9625240EBB16000E3791 /* RadioButtonLabelModel.swift */, 017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */, + D28764FA245A33A500CB882D /* TwoLinkViewModel.swift */, + D28764F8245A327200CB882D /* TwoLinkView.swift */, ); path = HorizontalCombinationViews; sourceTree = ""; @@ -2181,6 +2187,7 @@ 017BEB48236230DB0024EF95 /* MoleculeViewProtocol.swift in Sources */, D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */, 94382086243238D100B43AF3 /* WebViewModel.swift in Sources */, + D28764F9245A327200CB882D /* TwoLinkView.swift in Sources */, D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */, 0A6682B5243769C700AD3CA1 /* TextView.swift in Sources */, D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */, @@ -2273,6 +2280,7 @@ AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */, 011D9626240EBB16000E3791 /* RadioButtonLabelModel.swift in Sources */, 8DDD6C1D244D90B8006A2232 /* ListThreeColumnDataUsage.swift in Sources */, + D28764FB245A33A500CB882D /* TwoLinkViewModel.swift in Sources */, AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */, D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */, 944589232385DA9600DE9FD4 /* ImageViewModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 910ea202..cfeff322 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -92,6 +92,7 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Tabs.self, viewModelClass: TabsModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: TwoLinkView.self, viewModelClass: TwoLinkViewModel.self) // Vertical Combination Molecules MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift new file mode 100644 index 00000000..ed2ff2fb --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift @@ -0,0 +1,109 @@ +// +// TwoLinkView.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 4/29/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class TwoLinkView: View, MVMCoreUIViewConstrainingProtocol { + open var leftLink = Link() + open var rightLink = Link() + private var stack = UIStackView() + + public init() { + super.init(frame: .zero) + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + public override init(frame: CGRect) { + super.init(frame: frame) + } + + // MARK: - MVMCoreViewProtocol + open override func updateView(_ size: CGFloat) { + super.updateView(size) + stack.updateView(size) + } + + open override func setupView() { + super.setupView() + + stack.translatesAutoresizingMaskIntoConstraints = false + addSubview(stack) + stack.addArrangedSubview(leftLink) + stack.addArrangedSubview(rightLink) + NSLayoutConstraint.constraintPinSubview(toSuperview: stack) + stack.axis = .horizontal + stack.spacing = 8 + } + + // MARK: - Stack Manipulation + public func showRightLink() { + if !stack.arrangedSubviews.contains(rightLink) { + stack.addArrangedSubview(rightLink) + rightLink.isHidden = false + } + } + + public func showLeftLink() { + if !stack.arrangedSubviews.contains(leftLink) { + stack.insertArrangedSubview(leftLink, at: 0) + leftLink.isHidden = false + } + } + + public func hideRightLink() { + if rightLink.superview != nil { + stack.removeArrangedSubview(rightLink) + rightLink.isHidden = true + } + } + + public func hideLeftLink() { + if leftLink.superview != nil { + stack.removeArrangedSubview(leftLink) + leftLink.isHidden = true + } + } + + // MARK: - MoleculeViewProtocol + open override func reset() { + super.reset() + stack.reset() + } + + // MARK: - MVMCoreUIViewConstrainingProtocol + open func horizontalAlignment() -> UIStackView.Alignment { + return .center + } + + // MARK: - MoleculeViewProtocol + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 16 + } + + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) + + guard let model = model as? TwoLinkViewModel else { return } + + if let model = model.leftLink { + showLeftLink() + leftLink.set(with: model, delegateObject, additionalData) + } else { + hideLeftLink() + } + if let model = model.rightLink { + showRightLink() + rightLink.set(with: model, delegateObject, additionalData) + } else { + hideRightLink() + } + } +} diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift new file mode 100644 index 00000000..57962c09 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift @@ -0,0 +1,43 @@ +// +// TwoLinkViewModel.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 4/29/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class TwoLinkViewModel: MoleculeModelProtocol { + public static var identifier: String = "twoLinkView" + public var backgroundColor: Color? + public var rightLink: LinkModel? + public var leftLink: LinkModel? + + private enum CodingKeys: String, CodingKey { + case moleculeName + case backgroundColor + case rightLink + case leftLink + } + + public init(_ rightLink: LinkModel?, _ leftLink: LinkModel?) { + self.rightLink = rightLink + self.leftLink = leftLink + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + rightLink = try typeContainer.decodeIfPresent(LinkModel.self, forKey: .rightLink) + leftLink = try typeContainer.decodeIfPresent(LinkModel.self, forKey: .leftLink) + } + + 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(rightLink, forKey: .rightLink) + try container.encodeIfPresent(leftLink, forKey: .leftLink) + } +}