diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 208a22a2..b61c3aa1 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -244,6 +244,8 @@ AAB8549A24DC01DB00477C40 /* ListThreeColumnBillHistoryDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB8549924DC01DB00477C40 /* ListThreeColumnBillHistoryDivider.swift */; }; AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; }; AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatch.swift */; }; + AAC23FAD24D92A0D009208DF /* ListThreeColumnSpeedTestModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC23FAC24D92A0D009208DF /* ListThreeColumnSpeedTestModel.swift */; }; + AAC23FAF24D92A1E009208DF /* ListThreeColumnSpeedTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC23FAE24D92A1E009208DF /* ListThreeColumnSpeedTest.swift */; }; AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; }; AAE7270C24AC8B8500A3ED0E /* HeadersH2CaretLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE7270B24AC8B8500A3ED0E /* HeadersH2CaretLinkModel.swift */; }; AAE7270E24AC8B9300A3ED0E /* HeadersH2CaretLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE7270D24AC8B9300A3ED0E /* HeadersH2CaretLink.swift */; }; @@ -723,6 +725,8 @@ AAB8549924DC01DB00477C40 /* ListThreeColumnBillHistoryDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnBillHistoryDivider.swift; sourceTree = ""; }; AAB9C10724346F4B00151545 /* RadioSwatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatches.swift; sourceTree = ""; }; AAB9C109243496DD00151545 /* RadioSwatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatch.swift; sourceTree = ""; }; + AAC23FAC24D92A0D009208DF /* ListThreeColumnSpeedTestModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnSpeedTestModel.swift; sourceTree = ""; }; + AAC23FAE24D92A1E009208DF /* ListThreeColumnSpeedTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnSpeedTest.swift; sourceTree = ""; }; AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.swift; sourceTree = ""; }; AAE7270B24AC8B8500A3ED0E /* HeadersH2CaretLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2CaretLinkModel.swift; sourceTree = ""; }; AAE7270D24AC8B9300A3ED0E /* HeadersH2CaretLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2CaretLink.swift; sourceTree = ""; }; @@ -1164,6 +1168,8 @@ 323AC96B24C837FF00F8E4C4 /* ListThreeColumnBillChanges.swift */, AAA905DE24D1758700D1EFAB /* ListThreeColumnBillHistoryModel.swift */, AAA905E024D1759A00D1EFAB /* ListThreeColumnBillHistory.swift */, + AAC23FAC24D92A0D009208DF /* ListThreeColumnSpeedTestModel.swift */, + AAC23FAE24D92A1E009208DF /* ListThreeColumnSpeedTest.swift */, ); path = ThreeColumn; sourceTree = ""; @@ -2195,6 +2201,7 @@ 94C2D9A923872E5E0006CF46 /* LabelAttributeImageModel.swift in Sources */, DBC4391922442197001AB423 /* DashLine.swift in Sources */, D264FAAA2440F97600D98315 /* CollectionView.swift in Sources */, + AAC23FAD24D92A0D009208DF /* ListThreeColumnSpeedTestModel.swift in Sources */, BBC0C4FF24811DCA0087C44F /* TagModel.swift in Sources */, 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */, 3265B30424BCA749000D154B /* HeadersH1NoButtonsBodyText.swift in Sources */, @@ -2294,6 +2301,7 @@ 8D084AD22410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift in Sources */, 94C0150C2421564A005811A9 /* ActionCollapseNotificationModel.swift in Sources */, 014AA73123C5059B006F3E93 /* ListPageTemplateModel.swift in Sources */, + AAC23FAF24D92A1E009208DF /* ListThreeColumnSpeedTest.swift in Sources */, D29DF2A221E7AF4E003B2FB9 /* MVMCoreUIUtility.m in Sources */, D29DF12B21E6851E003B2FB9 /* MVMCoreUITopAlertExpandableView.m in Sources */, 94C2D9A723872DA90006CF46 /* LabelAttributeColorModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 248d3323..a08347c7 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -127,7 +127,6 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyToggle.self, viewModelClass: HeadlineBodyToggleModel.self) MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyLinkToggle.self, viewModelClass: HeadlineBodyLinkToggleModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ActionDetailWithImage.self, viewModelClass: ActionDetailWithImageModel.self) - MoleculeObjectMapping.shared()?.register(viewClass: LockupsPlanSMLXL.self, viewModelClass: LockupsPlanSMLXLModel.self) // MARK:- List items MoleculeObjectMapping.shared()?.register(viewClass: MoleculeTableViewCell.self, viewModelClass: MoleculeListItemModel.self) @@ -194,6 +193,7 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnDataUsage.self, viewModelClass: ListThreeColumnDataUsageModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnBillChanges.self, viewModelClass: ListThreeColumnBillChangesModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnBillHistory.self, viewModelClass: ListThreeColumnBillHistoryModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnSpeedTest.self, viewModelClass: ListThreeColumnSpeedTestModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListProgressBarThin.self, viewModelClass: ListProgressBarThinModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnSpeedTest.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnSpeedTest.swift new file mode 100644 index 00000000..28feb481 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnSpeedTest.swift @@ -0,0 +1,118 @@ +// +// ListThreeColumnSpeedTest.swift +// MVMCoreUI +// +// Created by Lekshmi S on 04/08/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class ListThreeColumnSpeedTest: TableViewCell { + //----------------------------------------------------- + // MARK: - Outlets + //------------------------------------------------------- + public var title = Label(fontStyle: .RegularMicro) + public var topLeftHeadlineBody = HeadlineBody() + public var topCenterHeadlineBody = HeadlineBody() + public var topRightHeadlineBody = HeadlineBody() + public var topHorizontalStack: Stack + public var bottomLeftHeadlineBody = HeadlineBody() + public var bottomCenterHeadlineBody = HeadlineBody() + public var bottomRightHeadlineBody = HeadlineBody() + public var bottomHorizontalStack: Stack + public var stack: Stack + + //------------------------------------------------------ + // MARK: - Initializers + //------------------------------------------------------ + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + topHorizontalStack = Stack.createStack(with: [(view: topLeftHeadlineBody, model: StackItemModel(percent: 37, verticalAlignment: .top)), (view: topCenterHeadlineBody, model: StackItemModel(percent: 33, verticalAlignment: .top)), (view: topRightHeadlineBody, model: StackItemModel(percent: 30, verticalAlignment: .top))], axis: .horizontal) + bottomHorizontalStack = Stack.createStack(with: [(view: bottomLeftHeadlineBody, model: StackItemModel(percent: 37, verticalAlignment: .top)), (view: bottomCenterHeadlineBody, model: StackItemModel(percent: 33, verticalAlignment: .top)), (view: bottomRightHeadlineBody, model: StackItemModel(percent: 30, verticalAlignment: .top))], axis: .horizontal) + stack = Stack.createStack(with: [(view: title, model: StackItemModel()), (view: topHorizontalStack, model: StackItemModel(spacing: 2)), (view: bottomHorizontalStack, model: StackItemModel())], axis: .vertical) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + //------------------------------------------------------ + // MARK: - Lifecycle + //------------------------------------------------------ + open override func setupView() { + super.setupView() + addMolecule(stack) + stack.restack() + topHorizontalStack.restack() + bottomHorizontalStack.restack() + } + + //-------------------------------------------------- + // 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? ListThreeColumnSpeedTestModel else { return } + title.set(with: model.title, delegateObject, additionalData) + topHorizontalStack.updateContainedMolecules(with: [model.topLeftHeadlineBody, model.topCenterHeadlineBody, model.topRightHeadlineBody], delegateObject, additionalData) + bottomHorizontalStack.updateContainedMolecules(with: [model.bottomLeftHeadlineBody, model.bottomCenterHeadlineBody, model.bottomRightHeadlineBody], delegateObject, additionalData) + updateAccessibilityLabel() + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 121 + } + + open override func reset() { + super.reset() + title.setFontStyle(.BoldBodySmall) + topLeftHeadlineBody.spaceBetweenLabelsConstant = 2 + topCenterHeadlineBody.spaceBetweenLabelsConstant = 2 + topRightHeadlineBody.spaceBetweenLabelsConstant = 2 + bottomLeftHeadlineBody.spaceBetweenLabelsConstant = 2 + bottomCenterHeadlineBody.spaceBetweenLabelsConstant = 2 + bottomRightHeadlineBody.spaceBetweenLabelsConstant = 2 + } + + //-------------------------------------------------- + // MARK: - Accessibility + //-------------------------------------------------- + func updateAccessibilityLabel() { + isAccessibilityElement = true + var message = "" + if let title = title.text, !title.isEmpty { + message += title + ", " + } + if let topLeftHeadlineBodyText = accessibilityTextOfHeadlineBody(topLeftHeadlineBody), !topLeftHeadlineBodyText.isEmpty { + message += topLeftHeadlineBodyText + ", " + } + if let topCenterHeadlineBodyText = accessibilityTextOfHeadlineBody(topCenterHeadlineBody), !topCenterHeadlineBodyText.isEmpty { + message += topCenterHeadlineBodyText + ", " + } + if let topRightHeadlineBodyText = accessibilityTextOfHeadlineBody(topRightHeadlineBody), !topRightHeadlineBodyText.isEmpty { + message += topRightHeadlineBodyText + ", " + } + if let bottomLeftHeadlineBodyText = accessibilityTextOfHeadlineBody(bottomLeftHeadlineBody), !bottomLeftHeadlineBodyText.isEmpty { + message += bottomLeftHeadlineBodyText + ", " + } + if let bottomCenterHeadlineBodyText = accessibilityTextOfHeadlineBody(bottomCenterHeadlineBody), !bottomCenterHeadlineBodyText.isEmpty { + message += bottomCenterHeadlineBodyText + ", " + } + if let bottomRightHeadlineBodyText = accessibilityTextOfHeadlineBody(bottomRightHeadlineBody), !bottomRightHeadlineBodyText.isEmpty { + message += bottomRightHeadlineBodyText + } + accessibilityLabel = message + } + + func accessibilityTextOfHeadlineBody(_ headlineBody: HeadlineBody) -> String? { + var message = "" + if let headlineLabel = headlineBody.headlineLabel.text { + message += headlineLabel + ", " + } + if let messageLabel = headlineBody.messageLabel.text { + message += messageLabel + } + return message + } +} diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnSpeedTestModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnSpeedTestModel.swift new file mode 100644 index 00000000..45a9af13 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ThreeColumn/ListThreeColumnSpeedTestModel.swift @@ -0,0 +1,104 @@ +// +// ListThreeColumnSpeedTestModel.swift +// MVMCoreUI +// +// Created by Lekshmi S on 04/08/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class ListThreeColumnSpeedTestModel: ListItemModel, MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "list3CSpdTst" + public var title: LabelModel + public var topLeftHeadlineBody: HeadlineBodyModel + public var topCenterHeadlineBody: HeadlineBodyModel + public var topRightHeadlineBody: HeadlineBodyModel + public var bottomLeftHeadlineBody: HeadlineBodyModel + public var bottomCenterHeadlineBody: HeadlineBodyModel + public var bottomRightHeadlineBody: HeadlineBodyModel + + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(title: LabelModel, topLeftHeadlineBody: HeadlineBodyModel, topCenterHeadlineBody: HeadlineBodyModel, topRightHeadlineBody: HeadlineBodyModel, bottomLeftHeadlineBody: HeadlineBodyModel, bottomCenterHeadlineBody: HeadlineBodyModel, bottomRightHeadlineBody: HeadlineBodyModel) { + self.title = title + self.topLeftHeadlineBody = topLeftHeadlineBody + self.topCenterHeadlineBody = topCenterHeadlineBody + self.topRightHeadlineBody = topRightHeadlineBody + self.bottomLeftHeadlineBody = bottomLeftHeadlineBody + self.bottomCenterHeadlineBody = bottomCenterHeadlineBody + self.bottomRightHeadlineBody = bottomRightHeadlineBody + super.init() + } + + //------------------------------------------------------ + // MARK: - Method + //------------------------------------------------------ + override public func setDefaults() { + styleHeadlineBody(topLeftHeadlineBody, true) + styleHeadlineBody(bottomLeftHeadlineBody, false) + styleHeadlineBody(topCenterHeadlineBody, false) + styleHeadlineBody(bottomCenterHeadlineBody, false) + styleHeadlineBody(topRightHeadlineBody, false) + styleHeadlineBody(bottomRightHeadlineBody, false) + super.setDefaults() + } + + //Method to style headline and body of HeadlineBody + func styleHeadlineBody(_ headlineBodyModel: HeadlineBodyModel, _ isBodyMicro: Bool) { + headlineBodyModel.headline?.fontStyle = .RegularMicro + headlineBodyModel.headline?.textColor = Color(uiColor: .mvmCoolGray6) + if isBodyMicro { + headlineBodyModel.body?.fontStyle = .RegularMicro + headlineBodyModel.body?.textColor = Color(uiColor: .mvmCoolGray6) + } else { + headlineBodyModel.body?.fontStyle = .RegularBodySmall + } + } + + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { + case moleculeName + case title + case topLeftHeadlineBody + case topCenterHeadlineBody + case topRightHeadlineBody + case bottomLeftHeadlineBody + case bottomCenterHeadlineBody + case bottomRightHeadlineBody + } + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + title = try typeContainer.decode(LabelModel.self, forKey: .title) + topLeftHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .topLeftHeadlineBody) + topCenterHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .topCenterHeadlineBody) + topRightHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .topRightHeadlineBody) + bottomLeftHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .bottomLeftHeadlineBody) + bottomCenterHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .bottomCenterHeadlineBody) + bottomRightHeadlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .bottomRightHeadlineBody) + 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(title, forKey: .title) + try container.encode(topLeftHeadlineBody, forKey: .topLeftHeadlineBody) + try container.encode(topCenterHeadlineBody, forKey: .topCenterHeadlineBody) + try container.encode(topRightHeadlineBody, forKey: .topRightHeadlineBody) + try container.encode(bottomLeftHeadlineBody, forKey: .bottomLeftHeadlineBody) + try container.encode(bottomCenterHeadlineBody, forKey: .bottomCenterHeadlineBody) + try container.encode(bottomRightHeadlineBody, forKey: .bottomRightHeadlineBody) + } +}