diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 339735f3..a26ef5f6 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -106,6 +106,8 @@ 52267A0723FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52267A0623FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift */; }; 5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5248BFEA23F12E350059236A /* ListThreeColumnPlanDataDivider.swift */; }; 5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */; }; + 525019DD2406430800EED91C /* ListProgressBarDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525019DB2406430700EED91C /* ListProgressBarDataModel.swift */; }; + 525019DE2406430800EED91C /* ListProgressBarData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525019DC2406430800EED91C /* ListProgressBarData.swift */; }; 525019E52406852100EED91C /* ListFourColumnDataUsageDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525019E42406852100EED91C /* ListFourColumnDataUsageDividerModel.swift */; }; 525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525019E62406853600EED91C /* ListFourColumnDataUsageDivider.swift */; }; 52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */; }; @@ -452,6 +454,8 @@ 52267A0623FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextAllTextAndLinks.swift; sourceTree = ""; }; 5248BFEA23F12E350059236A /* ListThreeColumnPlanDataDivider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnPlanDataDivider.swift; sourceTree = ""; }; 5248BFEB23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnPlanDataDividerModel.swift; sourceTree = ""; }; + 525019DB2406430700EED91C /* ListProgressBarDataModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListProgressBarDataModel.swift; sourceTree = ""; }; + 525019DC2406430800EED91C /* ListProgressBarData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListProgressBarData.swift; sourceTree = ""; }; 525019E42406852100EED91C /* ListFourColumnDataUsageDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageDividerModel.swift; sourceTree = ""; }; 525019E62406853600EED91C /* ListFourColumnDataUsageDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageDivider.swift; sourceTree = ""; }; 52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAndPaymentMethod.swift; sourceTree = ""; }; @@ -816,6 +820,15 @@ path = OneColumn; sourceTree = ""; }; + 525239C32407FFCC00454969 /* LockUps */ = { + isa = PBXGroup; + children = ( + 525019DB2406430700EED91C /* ListProgressBarDataModel.swift */, + 525019DC2406430800EED91C /* ListProgressBarData.swift */, + ); + path = LockUps; + sourceTree = ""; + }; 525019E3240684E500EED91C /* FourColumn */ = { isa = PBXGroup; children = ( @@ -1039,6 +1052,7 @@ D22B38E923F4E07800490EF6 /* DesignedComponents */ = { isa = PBXGroup; children = ( + 525239C32407FFCC00454969 /* LockUps */, D22B38EC23F4E10700490EF6 /* SectionDividers */, D22B38EA23F4E08B00490EF6 /* List */, ); @@ -1791,6 +1805,7 @@ D213347723843825008E41B3 /* Line.swift in Sources */, D28A837723C79FC600DFE4FC /* MFCustomButton+ActionModel.swift in Sources */, D2E2A99C23D8D975000B42E6 /* ImageHeadlineBodyModel.swift in Sources */, + 525019DE2406430800EED91C /* ListProgressBarData.swift in Sources */, D28A837F23CCA96400DFE4FC /* TabsModel.swift in Sources */, 012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */, D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */, @@ -1959,6 +1974,7 @@ D2A514592211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m in Sources */, 94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */, D21EE53C23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift in Sources */, + 525019DD2406430800EED91C /* ListProgressBarDataModel.swift in Sources */, C6FA7D5223C77A4A00A3614A /* UnOrderedList.swift in Sources */, 01509D8F2327EC6F00EF99AA /* MoleculeTableViewCell.swift in Sources */, 0105618D224BBE7700E1557D /* FormValidator.swift in Sources */, diff --git a/MVMCoreUI/Categories/NSLayoutConstraintExtension.swift b/MVMCoreUI/Categories/NSLayoutConstraintExtension.swift index 4057a88c..242e3fc0 100644 --- a/MVMCoreUI/Categories/NSLayoutConstraintExtension.swift +++ b/MVMCoreUI/Categories/NSLayoutConstraintExtension.swift @@ -10,48 +10,48 @@ import Foundation public extension NSLayoutConstraint { - /// Pins the views vertically in the super view, allowing the super to expand depending on the tallest view. Shorter views are aligned center. - static func pinViewsVerticalExpandableAlignCenter(_ views: [UIView]) { + /// Pins the views vertically to the top and bottom anchor, allowing the super to expand depending on the tallest view. Shorter views are aligned center. + static func pinViewsVerticalExpandableAlignCenter(_ views: [UIView], topAnchor: NSLayoutYAxisAnchor? = nil, bottomAnchor: NSLayoutYAxisAnchor? = nil, constant: CGFloat = 0) { for view in views { - guard let superView = view.superview else { - return - } + guard let superView = view.superview else { return } + let top = topAnchor ?? superView.layoutMarginsGuide.topAnchor + let bottom = bottomAnchor ?? superView.layoutMarginsGuide.bottomAnchor view.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true - view.topAnchor.constraint(greaterThanOrEqualTo: superView.layoutMarginsGuide.topAnchor).isActive = true - superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true + view.topAnchor.constraint(greaterThanOrEqualTo: top).isActive = true + bottom.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true - var constraint = view.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor) + var constraint = view.topAnchor.constraint(equalTo: top) constraint.priority = .defaultLow constraint.isActive = true - constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor) + constraint = bottom.constraint(equalTo: view.bottomAnchor) constraint.priority = .defaultLow constraint.isActive = true } } - /// Pins the views vertically in the super view, allowing the super to expand depending on the tallest view. Shorter views are aligned top. - static func pinViewsVerticalExpandableAlignTop(_ views: [UIView]) { + /// Pins the views vertically to the top and bottom anchor, allowing the super to expand depending on the tallest view. Shorter views are aligned top. + static func pinViewsVerticalExpandableAlignTop(_ views: [UIView], topAnchor: NSLayoutYAxisAnchor? = nil, bottomAnchor: NSLayoutYAxisAnchor? = nil, constant: CGFloat = 0) { for view in views { - guard let superView = view.superview else { - return - } - view.topAnchor.constraint(equalTo: superView.layoutMarginsGuide.topAnchor).isActive = true - superView.layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).isActive = true + guard let superView = view.superview else { return } + let top = topAnchor ?? superView.layoutMarginsGuide.topAnchor + let bottom = bottomAnchor ?? superView.layoutMarginsGuide.bottomAnchor + view.topAnchor.constraint(equalTo: top).isActive = true + bottom.constraint(greaterThanOrEqualTo: view.bottomAnchor, constant: constant).isActive = true - let constraint = superView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor) + let constraint = bottom.constraint(equalTo: view.bottomAnchor) constraint.priority = .defaultLow constraint.isActive = true } } /// Pins a view to the left and a view to the right, flexible space in between. The super can expand depending on the taller view. Shorter views are aligned top if alignTop true, else aligned center. - static func pinViews(leftView: UIView, rightView: UIView, alignTop: Bool) { + static func pinViews(leftView: UIView, rightView: UIView, alignTop: Bool, topAnchor: NSLayoutYAxisAnchor? = nil, bottomAnchor: NSLayoutYAxisAnchor? = nil, constant: CGFloat = 0) { guard let superView = leftView.superview else { return } if alignTop { - pinViewsVerticalExpandableAlignTop([leftView, rightView]) + pinViewsVerticalExpandableAlignTop([leftView, rightView], topAnchor: topAnchor, bottomAnchor: bottomAnchor, constant: constant) } else { - pinViewsVerticalExpandableAlignCenter([leftView, rightView]) + pinViewsVerticalExpandableAlignCenter([leftView, rightView], topAnchor: topAnchor, bottomAnchor: bottomAnchor, constant: constant) } leftView.leadingAnchor.constraint(equalTo: superView.layoutMarginsGuide.leadingAnchor).isActive = true superView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightView.trailingAnchor).isActive = true diff --git a/MVMCoreUI/Molecules/DesignedComponents/LockUps/ListProgressBarData.swift b/MVMCoreUI/Molecules/DesignedComponents/LockUps/ListProgressBarData.swift new file mode 100644 index 00000000..48f734ad --- /dev/null +++ b/MVMCoreUI/Molecules/DesignedComponents/LockUps/ListProgressBarData.swift @@ -0,0 +1,73 @@ +// +// ListProgressBarData.swift +// MVMCoreUI +// +// Created by Kruthika KP on 18/02/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers open class ListProgressBarData: TableViewCell { + + //----------------------------------------------------- + // MARK: - Outlets + //----------------------------------------------------- + let progressBar = MultiProgress(frame: .zero) + let leftLabel = Label.createLabelBoldBodySmall(true) + let rightLabel = Label.createLabelBoldBodySmall(true) + let view = MVMCoreUICommonViewsUtility.commonView() + + //----------------------------------------------------- + // MARK: - MFViewProtocol + //----------------------------------------------------- + override open func setupView() { + super.setupView() + + rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal) + view.addSubview(progressBar) + view.addSubview(leftLabel) + view.addSubview(rightLabel) + contentView.addSubview(view) + containerHelper.constrainView(view) + NSLayoutConstraint.pinViews(leftView: leftLabel, rightView: rightLabel, alignTop: true, bottomAnchor: progressBar.topAnchor, constant: 8) + progressBar.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true + progressBar.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true + view.bottomAnchor.constraint(equalTo: progressBar.bottomAnchor).isActive = true + } + + public override func updateView(_ size: CGFloat) { + super.updateView(size) + progressBar.updateView(size) + leftLabel.updateView(size) + rightLabel.updateView(size) + } + + //----------------------------------------------------- + // MARK: - ModelMoleculeViewProtocol + //----------------------------------------------------- + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListProgressBarDataModel else { return} + progressBar.set(with: model.progressBar, delegateObject, additionalData) + leftLabel.set(with: model.leftLabel, delegateObject, additionalData) + rightLabel.set(with: model.rightLabel, delegateObject, additionalData) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 90 + } + + //----------------------------------------------------- + // MARK: - MVMCoreUIMoleculeViewProtocol + //----------------------------------------------------- + override open func reset() { + super.reset() + progressBar.reset() + leftLabel.reset() + rightLabel.reset() + leftLabel.styleBoldBodySmall(true) + rightLabel.styleBoldBodySmall(true) + } +} + diff --git a/MVMCoreUI/Molecules/DesignedComponents/LockUps/ListProgressBarDataModel.swift b/MVMCoreUI/Molecules/DesignedComponents/LockUps/ListProgressBarDataModel.swift new file mode 100644 index 00000000..de6ada2e --- /dev/null +++ b/MVMCoreUI/Molecules/DesignedComponents/LockUps/ListProgressBarDataModel.swift @@ -0,0 +1,47 @@ +// +// ListProgressBarDataModel.swift +// MVMCoreUI +// +// Created by Kruthika KP on 18/02/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class ListProgressBarDataModel : ListItemModel, MoleculeModelProtocol { + public static var identifier: String = "listPrgBarData" + public var progressBar : MultiProgressBarModel + public var leftLabel: LabelModel + public var rightLabel: LabelModel + + public init (progressBar: MultiProgressBarModel, leftLabel: LabelModel, rightLabel: LabelModel){ + self.progressBar = progressBar + self.leftLabel = leftLabel + self.rightLabel = rightLabel + super.init() + } + + private enum CodingKeys: String, CodingKey{ + case moleculeName + case progressBar + case leftLabel + case rightLabel + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + progressBar = try typeContainer.decode(MultiProgressBarModel.self, forKey: .progressBar) + leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel) + rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(progressBar, forKey: .progressBar) + try container.encode(leftLabel, forKey: .leftLabel) + try container.encode(rightLabel, forKey: .rightLabel) + } +} diff --git a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/FourColumn/ListFourColumnDataUsageDivider.swift b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/FourColumn/ListFourColumnDataUsageDivider.swift index 35968599..8e37c16a 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/FourColumn/ListFourColumnDataUsageDivider.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/FourColumn/ListFourColumnDataUsageDivider.swift @@ -38,7 +38,7 @@ import Foundation stack.restack() } - // MARK: - MVMCoreUIMoleculeViewProtocol + // MARK: - ModelMoleculeViewProtocol open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.set(with: model, delegateObject, additionalData) guard let model = model as? ListFourColumnDataUsageDividerModel else { return } @@ -48,6 +48,10 @@ import Foundation label4.set(with: model.label4, delegateObject, additionalData) } + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 121 + } + // MARK: - MVMCoreUIMoleculeViewProtocol open override func reset() { super.reset() @@ -56,8 +60,4 @@ import Foundation label3.styleBoldBodySmall(true) label4.styleBoldBodySmall(true) } - - open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { - return 121 - } } diff --git a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift index 9adbe531..cc904a77 100644 --- a/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift +++ b/MVMCoreUI/Molecules/DesignedComponents/SectionDividers/ThreeColumn/ListThreeColumnPlanDataDivider.swift @@ -35,7 +35,7 @@ import Foundation stack.restack() } - // MARK: - MVMCoreUIMoleculeViewProtocol + // MARK: - ModelMoleculeViewProtocol open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.set(with: model, delegateObject, additionalData) guard let model = model as? ListThreeColumnPlanDataDividerModel else { return } diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index 34da2080..003b5d03 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -78,6 +78,8 @@ import Foundation MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: DropDownFilterTableViewCell.self, viewModelClass: DropDownListItemModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: AccordionMoleculeTableViewCell.self, viewModelClass: AccordionListItemModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: TabsTableViewCell.self, viewModelClass: TabsListItemModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListProgressBarData.self, viewModelClass: ListProgressBarDataModel.self) + // Other Items MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeStackItem.self, viewModelClass: MoleculeStackItemModel.self)