From c180abf30240a76f7fc4cd1a995381b781f4e981 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Tue, 31 Mar 2020 13:50:34 +0530 Subject: [PATCH 01/34] Radioswatches model initial commit --- MVMCoreUI.xcodeproj/project.pbxproj | 4 +++ .../Atoms/Buttons/RadioSwatchesModel.swift | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchesModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 03335a4d..7bd74df8 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -173,6 +173,7 @@ AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */; }; AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */; }; AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */; }; + AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; }; BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */; }; BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */; }; BB6C6AC0242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6ABE242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift */; }; @@ -556,6 +557,7 @@ AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePaymentsModel.swift; sourceTree = ""; }; AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyText.swift; sourceTree = ""; }; AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyTextModel.swift; sourceTree = ""; }; + AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.swift; sourceTree = ""; }; BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsectionModel.swift; sourceTree = ""; }; BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsection.swift; sourceTree = ""; }; BB6C6ABE242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerTallModel.swift; sourceTree = ""; }; @@ -1492,6 +1494,7 @@ 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */, 011D95AE2407266E000E3791 /* RadioButtonModel.swift */, 01004F2F22721C3800991ECC /* RadioButton.swift */, + AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */, ); path = Buttons; sourceTree = ""; @@ -1879,6 +1882,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */, 5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */, 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */, 8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchesModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchesModel.swift new file mode 100644 index 00000000..734ecbfd --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchesModel.swift @@ -0,0 +1,35 @@ +// +// RadioSwatchesModel.swift +// MVMCoreUI +// +// Created by Lekshmi S on 31/03/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers public class RadioSwatchesModel: MoleculeModelProtocol { + public var backgroundColor: Color? + public static var identifier: String = "radioSwatches" + public var moleculeName: String = RadioSwatchesModel.identifier + public var swatches: [RadioSwatchItemModel] + + public init(swatches: [RadioSwatchItemModel]) { + self.swatches = swatches + } +} + +@objcMembers public class RadioSwatchItemModel: MoleculeModelProtocol { + public var backgroundColor: Color? + public static var identifier: String = "radioSwatchItem" + public var moleculeName: String = RadioSwatchItemModel.identifier + public var text: String + public var enabled: Bool + public var color: Color + + public init(enabled: Bool, color: Color, text: String) { + self.enabled = enabled + self.color = color + self.text = text + } +} From 63f225398bdb11dde1e6bede8f2a3a91219304b4 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Tue, 7 Apr 2020 17:59:28 +0530 Subject: [PATCH 02/34] Added Radioswatches and radioswatchitem class files. --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ++ .../Atoms/Buttons/RadioSwatchItem.swift | 106 ++++++++++++++++++ .../Atomic/Atoms/Buttons/RadioSwatches.swift | 91 +++++++++++++++ .../Atoms/Buttons/RadioSwatchesModel.swift | 76 +++++++++++-- MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 3 + 5 files changed, 277 insertions(+), 7 deletions(-) create mode 100644 MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchItem.swift create mode 100644 MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatches.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 7bd74df8..36a87994 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -173,6 +173,8 @@ AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */; }; AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */; }; AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */; }; + AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; }; + AAB9C10A243496DD00151545 /* RadioSwatchItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatchItem.swift */; }; AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; }; BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */; }; BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */; }; @@ -557,6 +559,8 @@ AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePaymentsModel.swift; sourceTree = ""; }; AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyText.swift; sourceTree = ""; }; AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyTextModel.swift; sourceTree = ""; }; + AAB9C10724346F4B00151545 /* RadioSwatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatches.swift; sourceTree = ""; }; + AAB9C109243496DD00151545 /* RadioSwatchItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchItem.swift; sourceTree = ""; }; AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.swift; sourceTree = ""; }; BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsectionModel.swift; sourceTree = ""; }; BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsection.swift; sourceTree = ""; }; @@ -1495,6 +1499,8 @@ 011D95AE2407266E000E3791 /* RadioButtonModel.swift */, 01004F2F22721C3800991ECC /* RadioButton.swift */, AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */, + AAB9C10724346F4B00151545 /* RadioSwatches.swift */, + AAB9C109243496DD00151545 /* RadioSwatchItem.swift */, ); path = Buttons; sourceTree = ""; @@ -1897,6 +1903,7 @@ D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */, D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */, D28A838923CCCFCB00DFE4FC /* LinkModel.swift in Sources */, + AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */, 94C2D9A923872E5E0006CF46 /* LabelAttributeImageModel.swift in Sources */, DBC4391922442197001AB423 /* DashLine.swift in Sources */, 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */, @@ -1938,6 +1945,7 @@ D2E2A98323D8B32D000B42E6 /* EyebrowHeadlineBodyLinkModel.swift in Sources */, 012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */, BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */, + AAB9C10A243496DD00151545 /* RadioSwatchItem.swift in Sources */, D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */, 011D9602240DA20A000E3791 /* ValidProtocol.swift in Sources */, D260106323D0C05000764D80 /* StackItemModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchItem.swift b/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchItem.swift new file mode 100644 index 00000000..9693fe62 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchItem.swift @@ -0,0 +1,106 @@ +// +// RadioSwatchItem.swift +// MVMCoreUI +// +// Created by Lekshmi S on 01/04/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +open class RadioSwatchItem: UICollectionViewCell, MoleculeViewProtocol { + public var bottomText = Label.commonLabelB2(true) + let circleLayer = CAShapeLayer() + let outerCircleLayer = CAShapeLayer() + var cellView = MVMCoreUICommonViewsUtility.commonView() + var fillColor: Color = Color(uiColor: .mvmBlue) + + open override var isSelected: Bool { + didSet { + drawCircle() + isSelected ? drawOuterCircle() : removeOuterCircle() + isSelected ? (bottomText.isHidden = false) : (bottomText.isHidden = true) + } + } + + var isStrikeThrough: Bool = false { + didSet { + if isStrikeThrough { + drawStrikeThrough() + } + } + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + setupView() + } + + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setupView() + } + + public func drawCircle() { + circleLayer.path = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)).cgPath + circleLayer.fillColor = fillColor.cgColor + circleLayer.strokeColor = UIColor.mvmCoolGray6.cgColor + cellView.layer.addSublayer(circleLayer) + } + + public func drawStrikeThrough() { + let startPoint = CGPoint(x: 12, y: 30) + let endPoint = CGPoint(x: 42, y: 0) + let bezierPath = UIBezierPath() + bezierPath.move(to: startPoint) + bezierPath.addLine(to: endPoint) + let strikeThroughLayer = CAShapeLayer() + strikeThroughLayer.path = bezierPath.cgPath + strikeThroughLayer.strokeColor = UIColor.mvmBlack.cgColor + strikeThroughLayer.lineWidth = 1 + cellView.layer.addSublayer(strikeThroughLayer) + isUserInteractionEnabled = false + } + + public func drawOuterCircle() { + circleLayer.path = UIBezierPath(ovalIn: CGRect(x: 15, y: 4, width: 24, height: 24)).cgPath + outerCircleLayer.path = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)).cgPath + outerCircleLayer.name = "OuterCircle" + outerCircleLayer.strokeColor = UIColor.mvmCoolGray6.cgColor + outerCircleLayer.fillColor = UIColor.clear.cgColor + cellView.layer.addSublayer(outerCircleLayer) + } + + public func removeOuterCircle() { + circleLayer.path = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)).cgPath + self.cellView.layer.sublayers?.filter({$0.name == "OuterCircle"}).forEach({$0.removeFromSuperlayer()}) + } + + public func setupView() { + guard cellView.superview == nil else { + return + } + isAccessibilityElement = false + contentView.isAccessibilityElement = false + insetsLayoutMarginsFromSafeArea = false + contentView.insetsLayoutMarginsFromSafeArea = false + contentView.preservesSuperviewLayoutMargins = false + contentView.addSubview(cellView) + NSLayoutConstraint.constraintPinSubview(toSuperview: cellView) + cellView.addSubview(bottomText) + bottomText.textAlignment = .center + bottomText.topAnchor.constraint(equalTo: cellView.topAnchor, constant: 38).isActive = true + bottomText.leadingAnchor.constraint(equalTo: cellView.leadingAnchor).isActive = true + bottomText.trailingAnchor.constraint(equalTo: cellView.trailingAnchor).isActive = true + cellView.bottomAnchor.constraint(equalTo: bottomText.bottomAnchor).isActive = true + } + + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + guard let collectionModel = model as? RadioSwatchItemModel else { return } + fillColor = collectionModel.color + isSelected = collectionModel.selected ?? false + isUserInteractionEnabled = collectionModel.enabled ?? true + isStrikeThrough = collectionModel.strikethrough ?? false + bottomText.text = collectionModel.text + } +} diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatches.swift b/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatches.swift new file mode 100644 index 00000000..5c0c24be --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatches.swift @@ -0,0 +1,91 @@ +// +// RadioSwatches.swift +// MVMCoreUI +// +// Created by Lekshmi S on 01/04/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +open class RadioSwatches: View { + public let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + var swatches: [MoleculeModelProtocol]? + public var collectionViewHeight: NSLayoutConstraint? + + public let cellSize: Double = 54.0 + public let spacing: Double = 10 + + open override func setupView() { + super.setupView() + guard collectionView.superview == nil else { + return + } + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.dataSource = self + collectionView.delegate = self + collectionView.showsHorizontalScrollIndicator = false + collectionView.backgroundColor = .clear + collectionView.isAccessibilityElement = false + addSubview(collectionView) + NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView) + collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 100) + collectionViewHeight?.isActive = true + } + + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let radioSwatchesModel = model as? RadioSwatchesModel else { return } + collectionView.layer.borderColor = backgroundColor?.cgColor + registerCells() + setupLayout(with: radioSwatchesModel) + prepareMolecules(with: radioSwatchesModel) + collectionView.reloadData() + } + + func registerCells() { + collectionView.register(RadioSwatchItem.self, forCellWithReuseIdentifier: "RadioSwatchItemCollectionViewCell") + } + + func setupLayout(with radioSwatchesModel: RadioSwatchesModel?) { + let layout = UICollectionViewFlowLayout() + layout.scrollDirection = .vertical + layout.minimumLineSpacing = CGFloat(spacing) + layout.minimumInteritemSpacing = CGFloat(spacing) + collectionView.collectionViewLayout = layout + } + + func prepareMolecules(with radioSwatchesModel: RadioSwatchesModel?) { + guard let newSwatches = radioSwatchesModel?.swatches else { + swatches = nil + return + } + swatches = newSwatches + let collectionViewWidth = UIScreen.main.bounds.width - (2 * MFStyler.defaultHorizontalPaddingForApplicationWidth()) + let swatchesInRow = Double(floor(Double(collectionViewWidth/60.0))) + let numberOfRows = floor(Double(swatches?.count ?? 1)/swatchesInRow) + 1.0 + let height = (numberOfRows * cellSize) + (spacing * (numberOfRows-1)) + collectionViewHeight?.constant = CGFloat(height) + collectionViewHeight?.isActive = true + } +} + +extension RadioSwatches: UICollectionViewDelegateFlowLayout { + open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + return CGSize(width: cellSize, height: cellSize) + } +} + +extension RadioSwatches: UICollectionViewDataSource { + open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return swatches?.count ?? 0 + } + + open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + guard let molecule = swatches?[indexPath.row], let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioSwatchItemCollectionViewCell", for: indexPath) as? RadioSwatchItem else { + return UICollectionViewCell() + } + cell.set(with: molecule, nil, nil) + return cell + } +} diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchesModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchesModel.swift index 734ecbfd..ba6cddef 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchesModel.swift @@ -11,25 +11,87 @@ import Foundation @objcMembers public class RadioSwatchesModel: MoleculeModelProtocol { public var backgroundColor: Color? public static var identifier: String = "radioSwatches" - public var moleculeName: String = RadioSwatchesModel.identifier public var swatches: [RadioSwatchItemModel] public init(swatches: [RadioSwatchItemModel]) { self.swatches = swatches } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case backgroundColor + case swatches + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + self.swatches = try typeContainer.decode([RadioSwatchItemModel].self, forKey: .swatches) + self.backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + } + + 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.encode(swatches, forKey: .swatches) + } } @objcMembers public class RadioSwatchItemModel: MoleculeModelProtocol { public var backgroundColor: Color? public static var identifier: String = "radioSwatchItem" - public var moleculeName: String = RadioSwatchItemModel.identifier - public var text: String - public var enabled: Bool - public var color: Color + public var color: Color = Color(uiColor: .mvmBlue) + public var text: String? + public var selected: Bool? = false + public var enabled: Bool? = true + public var strikethrough: Bool? = false - public init(enabled: Bool, color: Color, text: String) { - self.enabled = enabled + public init(color: Color, text:String, selected: Bool, enabled: Bool, strikethrough: Bool) { self.color = color self.text = text + self.selected = selected + self.enabled = enabled + self.strikethrough = strikethrough + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case backgroundColor + case color + case text + case selected + case enabled + case strikethrough + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + color = try typeContainer.decode(Color.self, forKey: .color) + if let text = try typeContainer.decodeIfPresent(String.self, forKey: .text) { + self.text = text + } + if let selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) { + self.selected = selected + } + if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { + self.enabled = enabled + } + if let strikethrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) { + self.strikethrough = strikethrough + } + } + + 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.encode(color, forKey: .color) + try container.encode(text, forKey: .text) + try container.encode(selected, forKey: .selected) + try container.encode(enabled, forKey: .enabled) + try container.encode(strikethrough, forKey: .strikethrough) } } + + diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index bfa6db01..67a5cfed 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -111,6 +111,9 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: MoleculeStackItem.self, viewModelClass: MoleculeStackItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: StackItem.self, viewModelClass: StackItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: MoleculeCollectionViewCell.self, viewModelClass: CarouselItemModel.self) + + MoleculeObjectMapping.shared()?.register(viewClass: RadioSwatchItem.self, viewModelClass: RadioSwatchItemModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: RadioSwatches.self, viewModelClass: RadioSwatchesModel.self) // Other Container Molecules MoleculeObjectMapping.shared()?.register(viewClass: MoleculeHeaderView.self, viewModelClass: MoleculeHeaderModel.self) From 237ddb82251e2daefdaee2c591d9b427a2b0f6dc Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Tue, 7 Apr 2020 18:07:40 +0530 Subject: [PATCH 03/34] Added folder structure --- MVMCoreUI.xcodeproj/project.pbxproj | 22 +++++++++++++------ .../RadioSwatchItem.swift | 0 .../RadioSwatches.swift | 0 .../RadioSwatchesModel.swift | 0 4 files changed, 15 insertions(+), 7 deletions(-) rename MVMCoreUI/Atomic/Atoms/{Buttons => Selectors}/RadioSwatchItem.swift (100%) rename MVMCoreUI/Atomic/Atoms/{Buttons => Selectors}/RadioSwatches.swift (100%) rename MVMCoreUI/Atomic/Atoms/{Buttons => Selectors}/RadioSwatchesModel.swift (100%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index fad7e2e3..17ec4e42 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -182,11 +182,11 @@ AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */; }; AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */; }; AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */; }; - BB2C968F24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */; }; - BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */; }; AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; }; AAB9C10A243496DD00151545 /* RadioSwatchItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatchItem.swift */; }; AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; }; + BB2C968F24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */; }; + BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */; }; BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */; }; BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */; }; BB54C5202434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */; }; @@ -583,11 +583,11 @@ AA11A42023F15D7000D7962F /* ListRightVariablePaymentsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePaymentsModel.swift; sourceTree = ""; }; AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyText.swift; sourceTree = ""; }; AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyTextModel.swift; sourceTree = ""; }; - BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinksModel.swift; sourceTree = ""; }; - BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinks.swift; sourceTree = ""; }; AAB9C10724346F4B00151545 /* RadioSwatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatches.swift; sourceTree = ""; }; AAB9C109243496DD00151545 /* RadioSwatchItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchItem.swift; sourceTree = ""; }; AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.swift; sourceTree = ""; }; + BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinksModel.swift; sourceTree = ""; }; + BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinks.swift; sourceTree = ""; }; BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsectionModel.swift; sourceTree = ""; }; BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsection.swift; sourceTree = ""; }; BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableButtonAllTextAndLinks.swift; sourceTree = ""; }; @@ -1055,6 +1055,16 @@ path = RightVariable; sourceTree = ""; }; + AA56A26D243CAB0800303286 /* Selectors */ = { + isa = PBXGroup; + children = ( + AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */, + AAB9C10724346F4B00151545 /* RadioSwatches.swift */, + AAB9C109243496DD00151545 /* RadioSwatchItem.swift */, + ); + path = Selectors; + sourceTree = ""; + }; D202AFE2242A5F1400E5BEDF /* Extensions */ = { isa = PBXGroup; children = ( @@ -1425,6 +1435,7 @@ D29DF10D21E67A70003B2FB9 /* Atoms */ = { isa = PBXGroup; children = ( + AA56A26D243CAB0800303286 /* Selectors */, D29DF22B21E6A0FA003B2FB9 /* TextFields */, D29DF17D21E69E26003B2FB9 /* Views */, D29DF16821E69E1F003B2FB9 /* Buttons */, @@ -1565,9 +1576,6 @@ 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */, 011D95AE2407266E000E3791 /* RadioButtonModel.swift */, 01004F2F22721C3800991ECC /* RadioButton.swift */, - AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */, - AAB9C10724346F4B00151545 /* RadioSwatches.swift */, - AAB9C109243496DD00151545 /* RadioSwatchItem.swift */, ); path = Buttons; sourceTree = ""; diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchItem.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchItem.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatches.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatches.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Buttons/RadioSwatchesModel.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift From d351d6cd7c0a46bad043bcb6e9cdbb4f6049f4f3 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Tue, 7 Apr 2020 19:02:50 +0530 Subject: [PATCH 04/34] Code changes after review --- MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift index ba6cddef..d926ad5c 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift @@ -87,10 +87,10 @@ import Foundation try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(color, forKey: .color) - try container.encode(text, forKey: .text) - try container.encode(selected, forKey: .selected) - try container.encode(enabled, forKey: .enabled) - try container.encode(strikethrough, forKey: .strikethrough) + try container.encodeIfPresent(text, forKey: .text) + try container.encodeIfPresent(selected, forKey: .selected) + try container.encodeIfPresent(enabled, forKey: .enabled) + try container.encodeIfPresent(strikethrough, forKey: .strikethrough) } } From f46b9cb339502b7110bf8b7f093e9dff97480bcc Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Wed, 8 Apr 2020 19:57:27 +0530 Subject: [PATCH 05/34] Radio swatch elements - modify story commit --- .../Atomic/Atoms/Selectors/RadioSwatchItem.swift | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift index 9693fe62..3404f7f7 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift @@ -25,6 +25,7 @@ open class RadioSwatchItem: UICollectionViewCell, MoleculeViewProtocol { var isStrikeThrough: Bool = false { didSet { + cellView.layer.sublayers?.filter({$0.name == "OutOfStock"}).forEach({$0.removeFromSuperlayer()}) if isStrikeThrough { drawStrikeThrough() } @@ -44,7 +45,8 @@ open class RadioSwatchItem: UICollectionViewCell, MoleculeViewProtocol { public func drawCircle() { circleLayer.path = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)).cgPath circleLayer.fillColor = fillColor.cgColor - circleLayer.strokeColor = UIColor.mvmCoolGray6.cgColor + circleLayer.strokeColor = UIColor.mvmBlack.cgColor + circleLayer.lineWidth = 1 cellView.layer.addSublayer(circleLayer) } @@ -56,18 +58,19 @@ open class RadioSwatchItem: UICollectionViewCell, MoleculeViewProtocol { bezierPath.addLine(to: endPoint) let strikeThroughLayer = CAShapeLayer() strikeThroughLayer.path = bezierPath.cgPath - strikeThroughLayer.strokeColor = UIColor.mvmBlack.cgColor + strikeThroughLayer.name = "OutOfStock" + strikeThroughLayer.strokeColor = UIColor.mvmCoolGray6.cgColor strikeThroughLayer.lineWidth = 1 cellView.layer.addSublayer(strikeThroughLayer) - isUserInteractionEnabled = false } public func drawOuterCircle() { circleLayer.path = UIBezierPath(ovalIn: CGRect(x: 15, y: 4, width: 24, height: 24)).cgPath outerCircleLayer.path = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)).cgPath outerCircleLayer.name = "OuterCircle" - outerCircleLayer.strokeColor = UIColor.mvmCoolGray6.cgColor + outerCircleLayer.strokeColor = UIColor.mvmBlack.cgColor outerCircleLayer.fillColor = UIColor.clear.cgColor + outerCircleLayer.lineWidth = 1 cellView.layer.addSublayer(outerCircleLayer) } From 45901f31101876a9f456866a372fe43244b02161 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Thu, 9 Apr 2020 19:37:32 +0530 Subject: [PATCH 06/34] Added new keys and code changes. --- .../Atoms/Selectors/RadioSwatchItem.swift | 28 +++++++++-- .../Atoms/Selectors/RadioSwatches.swift | 48 ++++++++++++++++++- .../Atoms/Selectors/RadioSwatchesModel.swift | 28 ++++++++++- 3 files changed, 95 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift index 3404f7f7..17352ed7 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift @@ -9,12 +9,17 @@ import UIKit open class RadioSwatchItem: UICollectionViewCell, MoleculeViewProtocol { - public var bottomText = Label.commonLabelB2(true) + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public var bottomText = Label(frame: .zero) let circleLayer = CAShapeLayer() - let outerCircleLayer = CAShapeLayer() var cellView = MVMCoreUICommonViewsUtility.commonView() var fillColor: Color = Color(uiColor: .mvmBlue) - + + //------------------------------------------------------ + // MARK: - Property Observer + //------------------------------------------------------ open override var isSelected: Bool { didSet { drawCircle() @@ -32,6 +37,9 @@ open class RadioSwatchItem: UICollectionViewCell, MoleculeViewProtocol { } } + //------------------------------------------------------ + // MARK: - Initialization + //------------------------------------------------------ public override init(frame: CGRect) { super.init(frame: .zero) setupView() @@ -42,10 +50,15 @@ open class RadioSwatchItem: UICollectionViewCell, MoleculeViewProtocol { setupView() } + //------------------------------------------------------ + // MARK: - Drawing + //------------------------------------------------------ public func drawCircle() { + cellView.layer.sublayers?.filter({$0.name == "InnerCircle"}).forEach({$0.removeFromSuperlayer()}) circleLayer.path = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)).cgPath circleLayer.fillColor = fillColor.cgColor - circleLayer.strokeColor = UIColor.mvmBlack.cgColor + circleLayer.strokeColor = isUserInteractionEnabled ? UIColor.mvmBlack.cgColor : UIColor.mvmCoolGray6.cgColor + circleLayer.name = "InnerCircle" circleLayer.lineWidth = 1 cellView.layer.addSublayer(circleLayer) } @@ -65,7 +78,9 @@ open class RadioSwatchItem: UICollectionViewCell, MoleculeViewProtocol { } public func drawOuterCircle() { + self.cellView.layer.sublayers?.filter({$0.name == "OuterCircle"}).forEach({$0.removeFromSuperlayer()}) circleLayer.path = UIBezierPath(ovalIn: CGRect(x: 15, y: 4, width: 24, height: 24)).cgPath + let outerCircleLayer = CAShapeLayer() outerCircleLayer.path = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)).cgPath outerCircleLayer.name = "OuterCircle" outerCircleLayer.strokeColor = UIColor.mvmBlack.cgColor @@ -79,6 +94,9 @@ open class RadioSwatchItem: UICollectionViewCell, MoleculeViewProtocol { self.cellView.layer.sublayers?.filter({$0.name == "OuterCircle"}).forEach({$0.removeFromSuperlayer()}) } + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- public func setupView() { guard cellView.superview == nil else { return @@ -92,6 +110,7 @@ open class RadioSwatchItem: UICollectionViewCell, MoleculeViewProtocol { NSLayoutConstraint.constraintPinSubview(toSuperview: cellView) cellView.addSubview(bottomText) bottomText.textAlignment = .center + bottomText.font = MFFonts.mfFontTXRegular(11.0) bottomText.topAnchor.constraint(equalTo: cellView.topAnchor, constant: 38).isActive = true bottomText.leadingAnchor.constraint(equalTo: cellView.leadingAnchor).isActive = true bottomText.trailingAnchor.constraint(equalTo: cellView.trailingAnchor).isActive = true @@ -101,7 +120,6 @@ open class RadioSwatchItem: UICollectionViewCell, MoleculeViewProtocol { public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let collectionModel = model as? RadioSwatchItemModel else { return } fillColor = collectionModel.color - isSelected = collectionModel.selected ?? false isUserInteractionEnabled = collectionModel.enabled ?? true isStrikeThrough = collectionModel.strikethrough ?? false bottomText.text = collectionModel.text diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift index 5c0c24be..a27af6c8 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift @@ -9,13 +9,29 @@ import UIKit open class RadioSwatches: View { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- public let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) - var swatches: [MoleculeModelProtocol]? - public var collectionViewHeight: NSLayoutConstraint? + var swatches: [RadioSwatchItemModel]? + public var selectedSwatchItem: RadioSwatchItemModel? { + get{ + guard let selectedItem = collectionView.indexPathsForSelectedItems?.first else {return nil} + return swatches?[selectedItem.item] + } + } + + //------------------------------------------------------ + // MARK: - Constraints + //------------------------------------------------------ + public var collectionViewHeight: NSLayoutConstraint? public let cellSize: Double = 54.0 public let spacing: Double = 10 + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- open override func setupView() { super.setupView() guard collectionView.superview == nil else { @@ -33,6 +49,17 @@ open class RadioSwatches: View { collectionViewHeight?.isActive = true } + public override func updateView(_ size: CGFloat) { + DispatchQueue.main.async { + self.collectionView.collectionViewLayout.invalidateLayout() + self.collectionView.reloadData() + guard let selectedCell = self.swatches?.firstIndex(where: {$0.selected == true}) else { + return + } + self.collectionView.selectItem(at: IndexPath(item: selectedCell, section: 0), animated: true, scrollPosition: .centeredHorizontally) + } + } + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) guard let radioSwatchesModel = model as? RadioSwatchesModel else { return } @@ -43,6 +70,9 @@ open class RadioSwatches: View { collectionView.reloadData() } + //------------------------------------------------------ + // MARK: - Methods + //------------------------------------------------------ func registerCells() { collectionView.register(RadioSwatchItem.self, forCellWithReuseIdentifier: "RadioSwatchItemCollectionViewCell") } @@ -70,6 +100,9 @@ open class RadioSwatches: View { } } +//------------------------------------------------------ +// MARK: - Delegate methods +//------------------------------------------------------ extension RadioSwatches: UICollectionViewDelegateFlowLayout { open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: cellSize, height: cellSize) @@ -89,3 +122,14 @@ extension RadioSwatches: UICollectionViewDataSource { return cell } } + +extension RadioSwatches: UICollectionViewDelegate { + public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + guard let swatchItem = swatches?[indexPath.row] else { return } + swatchItem.selected = true + } + public func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { + guard let swatchItem = swatches?[indexPath.row] else { return } + swatchItem.selected = false + } +} diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift index d926ad5c..e5e0ce11 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift @@ -37,7 +37,7 @@ import Foundation } } -@objcMembers public class RadioSwatchItemModel: MoleculeModelProtocol { +@objcMembers public class RadioSwatchItemModel: MoleculeModelProtocol, FormFieldProtocol { public var backgroundColor: Color? public static var identifier: String = "radioSwatchItem" public var color: Color = Color(uiColor: .mvmBlue) @@ -45,13 +45,25 @@ import Foundation public var selected: Bool? = false public var enabled: Bool? = true public var strikethrough: Bool? = false + public var fieldKey: String? + public var fieldValue: String? + public var baseValue: AnyHashable? + public var groupName: String = FormValidator.defaultGroupName - public init(color: Color, text:String, selected: Bool, enabled: Bool, strikethrough: Bool) { + public init(color: Color, text:String, selected: Bool, enabled: Bool, strikethrough: Bool, fieldKey: String, fieldValue: String, groupName:String) { self.color = color self.text = text self.selected = selected + self.fieldValue = fieldValue self.enabled = enabled self.strikethrough = strikethrough + self.fieldKey = fieldKey + self.groupName = groupName + baseValue = selected + } + + public func formFieldValue() -> AnyHashable? { + return selected } private enum CodingKeys: String, CodingKey { @@ -62,6 +74,9 @@ import Foundation case selected case enabled case strikethrough + case fieldKey + case fieldValue + case groupName } required public init(from decoder: Decoder) throws { @@ -80,6 +95,12 @@ import Foundation if let strikethrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) { self.strikethrough = strikethrough } + baseValue = self.selected + fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) + fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue) + if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { + self.groupName = groupName + } } public func encode(to encoder: Encoder) throws { @@ -91,6 +112,9 @@ import Foundation try container.encodeIfPresent(selected, forKey: .selected) try container.encodeIfPresent(enabled, forKey: .enabled) try container.encodeIfPresent(strikethrough, forKey: .strikethrough) + try container.encodeIfPresent(fieldKey, forKey: .fieldKey) + try container.encodeIfPresent(fieldValue, forKey: .fieldValue) + try container.encodeIfPresent(groupName, forKey: .groupName) } } From 5a30f99d62f260f83237d2b5e9d48648e82c04e8 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Mon, 13 Apr 2020 10:22:30 +0530 Subject: [PATCH 07/34] Re-arranged folder structure. --- MVMCoreUI.xcodeproj/project.pbxproj | 14 +++----------- .../Atoms/{Selectors => }/RadioSwatchItem.swift | 0 .../Atoms/{Selectors => }/RadioSwatches.swift | 0 .../Atoms/{Selectors => }/RadioSwatchesModel.swift | 0 4 files changed, 3 insertions(+), 11 deletions(-) rename MVMCoreUI/Atomic/Atoms/{Selectors => }/RadioSwatchItem.swift (100%) rename MVMCoreUI/Atomic/Atoms/{Selectors => }/RadioSwatches.swift (100%) rename MVMCoreUI/Atomic/Atoms/{Selectors => }/RadioSwatchesModel.swift (100%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 5bcd1a74..08fbd249 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -1069,16 +1069,6 @@ path = TwoColumn; sourceTree = ""; }; - AA56A26D243CAB0800303286 /* Selectors */ = { - isa = PBXGroup; - children = ( - AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */, - AAB9C10724346F4B00151545 /* RadioSwatches.swift */, - AAB9C109243496DD00151545 /* RadioSwatchItem.swift */, - ); - path = Selectors; - sourceTree = ""; - }; D202AFE2242A5F1400E5BEDF /* Extensions */ = { isa = PBXGroup; children = ( @@ -1453,7 +1443,9 @@ D29DF10D21E67A70003B2FB9 /* Atoms */ = { isa = PBXGroup; children = ( - AA56A26D243CAB0800303286 /* Selectors */, + AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */, + AAB9C10724346F4B00151545 /* RadioSwatches.swift */, + AAB9C109243496DD00151545 /* RadioSwatchItem.swift */, D29DF22B21E6A0FA003B2FB9 /* TextFields */, D29DF17D21E69E26003B2FB9 /* Views */, D29DF16821E69E1F003B2FB9 /* Buttons */, diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift b/MVMCoreUI/Atomic/Atoms/RadioSwatchItem.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift rename to MVMCoreUI/Atomic/Atoms/RadioSwatchItem.swift diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift b/MVMCoreUI/Atomic/Atoms/RadioSwatches.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift rename to MVMCoreUI/Atomic/Atoms/RadioSwatches.swift diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift b/MVMCoreUI/Atomic/Atoms/RadioSwatchesModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift rename to MVMCoreUI/Atomic/Atoms/RadioSwatchesModel.swift From 163535398925b20ec54f2ccf7306ef64f9d1bf1e Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Mon, 13 Apr 2020 18:07:54 +0530 Subject: [PATCH 08/34] Code refactoring by using collection base classes. --- MVMCoreUI.xcodeproj/project.pbxproj | 10 +- MVMCoreUI/Atomic/Atoms/RadioSwatchItem.swift | 127 ------------- .../Atoms/Selectors/RadioSwatchItem.swift | 167 ++++++++++++++++++ .../RadioSwatchItemCollectionViewCell.swift | 24 +++ .../Atoms/{ => Selectors}/RadioSwatches.swift | 113 ++++++------ .../{ => Selectors}/RadioSwatchesModel.swift | 53 +++--- MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 1 + 7 files changed, 280 insertions(+), 215 deletions(-) delete mode 100644 MVMCoreUI/Atomic/Atoms/RadioSwatchItem.swift create mode 100644 MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift create mode 100644 MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift rename MVMCoreUI/Atomic/Atoms/{ => Selectors}/RadioSwatches.swift (54%) rename MVMCoreUI/Atomic/Atoms/{ => Selectors}/RadioSwatchesModel.swift (86%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 3e55a236..077b0ca2 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -190,6 +190,7 @@ AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA1EC59824373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift */; }; AA56A20F243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA56A20E243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift */; }; AA56A211243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA56A210243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift */; }; + AA85236C244435A20059CC1E /* RadioSwatchItemCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA85236B244435A20059CC1E /* RadioSwatchItemCollectionViewCell.swift */; }; AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */; }; AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */; }; AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; }; @@ -619,6 +620,7 @@ AA1EC59824373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnSpeedTestDivider.swift; sourceTree = ""; }; AA56A20E243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnSubsectionDividerModel.swift; sourceTree = ""; }; AA56A210243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnSubsectionDivider.swift; sourceTree = ""; }; + AA85236B244435A20059CC1E /* RadioSwatchItemCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchItemCollectionViewCell.swift; sourceTree = ""; }; AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyText.swift; sourceTree = ""; }; AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyTextModel.swift; sourceTree = ""; }; AAB9C10724346F4B00151545 /* RadioSwatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatches.swift; sourceTree = ""; }; @@ -1435,6 +1437,10 @@ 01004F2F22721C3800991ECC /* RadioButton.swift */, 31BE15CA23D8924C00452370 /* CheckboxModel.swift */, 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */, + AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */, + AAB9C10724346F4B00151545 /* RadioSwatches.swift */, + AAB9C109243496DD00151545 /* RadioSwatchItem.swift */, + AA85236B244435A20059CC1E /* RadioSwatchItemCollectionViewCell.swift */, ); path = Selectors; sourceTree = ""; @@ -1515,9 +1521,6 @@ isa = PBXGroup; children = ( D264FAA8243FE17A00D98315 /* Selectors */, - AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */, - AAB9C10724346F4B00151545 /* RadioSwatches.swift */, - AAB9C109243496DD00151545 /* RadioSwatchItem.swift */, D29DF22B21E6A0FA003B2FB9 /* TextFields */, D29DF17D21E69E26003B2FB9 /* Views */, D29DF16821E69E1F003B2FB9 /* Buttons */, @@ -2330,6 +2333,7 @@ 0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */, AA56A211243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift in Sources */, D264FA8C243BCD8E00D98315 /* CollectionTemplateModel.swift in Sources */, + AA85236C244435A20059CC1E /* RadioSwatchItemCollectionViewCell.swift in Sources */, 52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */, D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */, 0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/RadioSwatchItem.swift b/MVMCoreUI/Atomic/Atoms/RadioSwatchItem.swift deleted file mode 100644 index 17352ed7..00000000 --- a/MVMCoreUI/Atomic/Atoms/RadioSwatchItem.swift +++ /dev/null @@ -1,127 +0,0 @@ -// -// RadioSwatchItem.swift -// MVMCoreUI -// -// Created by Lekshmi S on 01/04/20. -// Copyright © 2020 Verizon Wireless. All rights reserved. -// - -import UIKit - -open class RadioSwatchItem: UICollectionViewCell, MoleculeViewProtocol { - //-------------------------------------------------- - // MARK: - Properties - //-------------------------------------------------- - public var bottomText = Label(frame: .zero) - let circleLayer = CAShapeLayer() - var cellView = MVMCoreUICommonViewsUtility.commonView() - var fillColor: Color = Color(uiColor: .mvmBlue) - - //------------------------------------------------------ - // MARK: - Property Observer - //------------------------------------------------------ - open override var isSelected: Bool { - didSet { - drawCircle() - isSelected ? drawOuterCircle() : removeOuterCircle() - isSelected ? (bottomText.isHidden = false) : (bottomText.isHidden = true) - } - } - - var isStrikeThrough: Bool = false { - didSet { - cellView.layer.sublayers?.filter({$0.name == "OutOfStock"}).forEach({$0.removeFromSuperlayer()}) - if isStrikeThrough { - drawStrikeThrough() - } - } - } - - //------------------------------------------------------ - // MARK: - Initialization - //------------------------------------------------------ - public override init(frame: CGRect) { - super.init(frame: .zero) - setupView() - } - - public required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - setupView() - } - - //------------------------------------------------------ - // MARK: - Drawing - //------------------------------------------------------ - public func drawCircle() { - cellView.layer.sublayers?.filter({$0.name == "InnerCircle"}).forEach({$0.removeFromSuperlayer()}) - circleLayer.path = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)).cgPath - circleLayer.fillColor = fillColor.cgColor - circleLayer.strokeColor = isUserInteractionEnabled ? UIColor.mvmBlack.cgColor : UIColor.mvmCoolGray6.cgColor - circleLayer.name = "InnerCircle" - circleLayer.lineWidth = 1 - cellView.layer.addSublayer(circleLayer) - } - - public func drawStrikeThrough() { - let startPoint = CGPoint(x: 12, y: 30) - let endPoint = CGPoint(x: 42, y: 0) - let bezierPath = UIBezierPath() - bezierPath.move(to: startPoint) - bezierPath.addLine(to: endPoint) - let strikeThroughLayer = CAShapeLayer() - strikeThroughLayer.path = bezierPath.cgPath - strikeThroughLayer.name = "OutOfStock" - strikeThroughLayer.strokeColor = UIColor.mvmCoolGray6.cgColor - strikeThroughLayer.lineWidth = 1 - cellView.layer.addSublayer(strikeThroughLayer) - } - - public func drawOuterCircle() { - self.cellView.layer.sublayers?.filter({$0.name == "OuterCircle"}).forEach({$0.removeFromSuperlayer()}) - circleLayer.path = UIBezierPath(ovalIn: CGRect(x: 15, y: 4, width: 24, height: 24)).cgPath - let outerCircleLayer = CAShapeLayer() - outerCircleLayer.path = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)).cgPath - outerCircleLayer.name = "OuterCircle" - outerCircleLayer.strokeColor = UIColor.mvmBlack.cgColor - outerCircleLayer.fillColor = UIColor.clear.cgColor - outerCircleLayer.lineWidth = 1 - cellView.layer.addSublayer(outerCircleLayer) - } - - public func removeOuterCircle() { - circleLayer.path = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)).cgPath - self.cellView.layer.sublayers?.filter({$0.name == "OuterCircle"}).forEach({$0.removeFromSuperlayer()}) - } - - //-------------------------------------------------- - // MARK: - Lifecycle - //-------------------------------------------------- - public func setupView() { - guard cellView.superview == nil else { - return - } - isAccessibilityElement = false - contentView.isAccessibilityElement = false - insetsLayoutMarginsFromSafeArea = false - contentView.insetsLayoutMarginsFromSafeArea = false - contentView.preservesSuperviewLayoutMargins = false - contentView.addSubview(cellView) - NSLayoutConstraint.constraintPinSubview(toSuperview: cellView) - cellView.addSubview(bottomText) - bottomText.textAlignment = .center - bottomText.font = MFFonts.mfFontTXRegular(11.0) - bottomText.topAnchor.constraint(equalTo: cellView.topAnchor, constant: 38).isActive = true - bottomText.leadingAnchor.constraint(equalTo: cellView.leadingAnchor).isActive = true - bottomText.trailingAnchor.constraint(equalTo: cellView.trailingAnchor).isActive = true - cellView.bottomAnchor.constraint(equalTo: bottomText.bottomAnchor).isActive = true - } - - public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - guard let collectionModel = model as? RadioSwatchItemModel else { return } - fillColor = collectionModel.color - isUserInteractionEnabled = collectionModel.enabled ?? true - isStrikeThrough = collectionModel.strikethrough ?? false - bottomText.text = collectionModel.text - } -} diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift new file mode 100644 index 00000000..f6054ebb --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift @@ -0,0 +1,167 @@ +// +// RadioSwatchItem.swift +// MVMCoreUI +// +// Created by Lekshmi S on 01/04/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +import UIKit + +open class RadioSwatchItem: Control { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public var bottomText = Label.createLabelRegularMicro(true) + public var isOutOfStock = false + public var fillColor: Color = Color(uiColor: .mvmBlue) + + private var circleLayer: CAShapeLayer? + private var selectedLayer: CALayer? + private var strikeLayer: CALayer? + private var maskLayer: CALayer? + + public var radioSwatchModel: RadioSwatchItemModel? { + return model as? RadioSwatchItemModel + } + + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + open override func updateView(_ size: CGFloat) { + super.updateView(size) + bottomText.updateView(size) + layer.setNeedsDisplay() + } + + public override func setupView() { + super.setupView() + + addSubview(bottomText) + bottomText.textAlignment = .center + bottomText.topAnchor.constraint(equalTo: topAnchor, constant: 38).isActive = true + bottomText.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true + bottomText.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true + bottomAnchor.constraint(equalTo: bottomText.bottomAnchor).isActive = true + addTarget(self, action: #selector(selectSwatch), for: .touchUpInside) + } + + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? RadioSwatchItemModel else { return } + fillColor = model.color + isSelected = model.selected ?? false + isEnabled = model.enabled ?? true + bottomText.text = model.text + isOutOfStock = model.strikethrough ?? false + } + + //------------------------------------------------------ + // MARK: - State Handling + //------------------------------------------------------ + + open override func draw(_ layer: CALayer, in ctx: CGContext) { + //Draw the swatch + circleLayer?.removeFromSuperlayer() + let circle = getCircle(color: UIColor.mvmBlack, thickness: 1) + layer.addSublayer(circle) + circleLayer = circle + + //Draw the strikethrough + strikeLayer?.removeFromSuperlayer() + if isOutOfStock { + let line = getStrikeThrough(color: UIColor.mvmCoolGray6, thickness: 1) + layer.addSublayer(line) + strikeLayer = line + } + + //Draw the selected layer + selectedLayer?.removeFromSuperlayer() + if isSelected { + let outerCircle = getSelectedLayer(color: UIColor.black, thickness: 1) + layer.addSublayer(outerCircle) + selectedLayer = outerCircle + bottomText.isHidden = false + } else { + circleLayer?.path = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)).cgPath + bottomText.isHidden = true + } + + //Handle Mask + maskLayer?.removeFromSuperlayer() + if !isEnabled { + let mask = getMaskLayer() + layer.mask = mask + maskLayer = mask + } + } + + open override func layoutSubviews() { + super.layoutSubviews() + // Accounts for any size changes + layer.setNeedsDisplay() + } + + @objc open func selectSwatch() { + isSelected = true + radioSwatchModel?.selected = isSelected + layer.setNeedsDisplay() + } + + @objc open func deselectSwatch() { + isSelected = false + radioSwatchModel?.selected = isSelected + layer.setNeedsDisplay() + } + + func getCircle(color: UIColor, thickness: CGFloat) -> CAShapeLayer { + let circle = CAShapeLayer() + circle.name = "innercircle" + circle.fillColor = fillColor.cgColor + circle.opacity = 1.0 + circle.lineWidth = thickness + circle.strokeColor = isEnabled ? color.cgColor : UIColor.mvmCoolGray6.cgColor + + let circlePath = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)) + circle.path = circlePath.cgPath + return circle + } + + func getStrikeThrough(color: UIColor, thickness: CGFloat) -> CAShapeLayer { + let strikeThrough = CAShapeLayer() + strikeThrough.name = "strikethrough" + strikeThrough.fillColor = nil + strikeThrough.opacity = 1.0 + strikeThrough.lineWidth = thickness + strikeThrough.strokeColor = color.cgColor + + let linePath = UIBezierPath() + linePath.move(to: CGPoint(x: 12, y: 30)) + linePath.addLine(to: CGPoint(x: 42, y: 0)) + strikeThrough.path = linePath.cgPath + return strikeThrough + } + + func getSelectedLayer(color: UIColor, thickness: CGFloat) -> CAShapeLayer { + circleLayer?.path = UIBezierPath(ovalIn: CGRect(x: 15, y: 4, width: 24, height: 24)).cgPath + let circle = CAShapeLayer() + circle.name = "outercircle" + circle.fillColor = UIColor.clear.cgColor + circle.opacity = 1.0 + circle.lineWidth = thickness + circle.strokeColor = color.cgColor + + let circlePath = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)) + circle.path = circlePath.cgPath + return circle + } + + func getMaskLayer() -> CALayer { + let mask = CALayer() + mask.backgroundColor = UIColor.white.cgColor + mask.opacity = 0.3 + mask.frame = bounds + return mask + } +} diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift new file mode 100644 index 00000000..b274d28d --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift @@ -0,0 +1,24 @@ +// +// RadioSwatchItemCollectionViewCell.swift +// MVMCoreUI +// +// Created by Lekshmi S on 13/04/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +open class RadioSwatchItemCollectionViewCell: CollectionViewCell { + let radioSwatch = RadioSwatchItem() + + open override func setupView() { + super.setupView() + addMolecule(radioSwatch) + MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0) + } + + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + guard let model = model as? RadioSwatchItemModel else { return } + radioSwatch.set(with: model, delegateObject, additionalData) + self.isUserInteractionEnabled = model.enabled ?? true + } +} diff --git a/MVMCoreUI/Atomic/Atoms/RadioSwatches.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift similarity index 54% rename from MVMCoreUI/Atomic/Atoms/RadioSwatches.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift index a27af6c8..d73c749a 100644 --- a/MVMCoreUI/Atomic/Atoms/RadioSwatches.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift @@ -6,97 +6,97 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import UIKit +import Foundation open class RadioSwatches: View { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - public let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + public var collectionView: CollectionView! var swatches: [RadioSwatchItemModel]? - - public var selectedSwatchItem: RadioSwatchItemModel? { - get{ - guard let selectedItem = collectionView.indexPathsForSelectedItems?.first else {return nil} - return swatches?[selectedItem.item] - } - } + private var size: CGFloat? + private var delegateObject: MVMCoreUIDelegateObject? //------------------------------------------------------ // MARK: - Constraints //------------------------------------------------------ public var collectionViewHeight: NSLayoutConstraint? - public let cellSize: Double = 54.0 - public let spacing: Double = 10 + private let cellSize: CGFloat = 54.0 + private let itemSpacing: CGFloat = 8.0 //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- + open override func layoutSubviews() { + super.layoutSubviews() + // Accounts for any collection size changes + DispatchQueue.main.async { + self.collectionView.collectionViewLayout.invalidateLayout() + } + } + open override func setupView() { super.setupView() - guard collectionView.superview == nil else { - return - } - collectionView.translatesAutoresizingMaskIntoConstraints = false - collectionView.dataSource = self - collectionView.delegate = self - collectionView.showsHorizontalScrollIndicator = false - collectionView.backgroundColor = .clear - collectionView.isAccessibilityElement = false + collectionView = createCollectionView() addSubview(collectionView) NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView) collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 100) collectionViewHeight?.isActive = true } - public override func updateView(_ size: CGFloat) { - DispatchQueue.main.async { - self.collectionView.collectionViewLayout.invalidateLayout() - self.collectionView.reloadData() - guard let selectedCell = self.swatches?.firstIndex(where: {$0.selected == true}) else { - return - } - self.collectionView.selectItem(at: IndexPath(item: selectedCell, section: 0), animated: true, scrollPosition: .centeredHorizontally) - } + @objc override open func updateView(_ size: CGFloat) { + super.updateView(size) + self.size = size + collectionView.updateView(size) } public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) + self.delegateObject = delegateObject + guard let radioSwatchesModel = model as? RadioSwatchesModel else { return } - collectionView.layer.borderColor = backgroundColor?.cgColor + swatches = radioSwatchesModel.swatches + FormValidator.setupValidation(for: radioSwatchesModel, delegate: delegateObject?.formHolderDelegate) registerCells() - setupLayout(with: radioSwatchesModel) - prepareMolecules(with: radioSwatchesModel) + setHeight() collectionView.reloadData() } //------------------------------------------------------ // MARK: - Methods //------------------------------------------------------ - func registerCells() { - collectionView.register(RadioSwatchItem.self, forCellWithReuseIdentifier: "RadioSwatchItemCollectionViewCell") + open func registerCells() { + collectionView.register(RadioSwatchItemCollectionViewCell.self, forCellWithReuseIdentifier: "RadioSwatchItemCollectionViewCell") } - func setupLayout(with radioSwatchesModel: RadioSwatchesModel?) { + /// Creates the collection view. + open func createCollectionView() -> CollectionView { + let collection = CollectionView(frame: .zero, collectionViewLayout: createCollectionViewLayout()) + collection.dataSource = self + collection.delegate = self + return collection + } + + /// Creates the layout for the collection. + open func createCollectionViewLayout() -> UICollectionViewLayout { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .vertical - layout.minimumLineSpacing = CGFloat(spacing) - layout.minimumInteritemSpacing = CGFloat(spacing) - collectionView.collectionViewLayout = layout + layout.minimumLineSpacing = itemSpacing + layout.minimumInteritemSpacing = itemSpacing + return layout } - func prepareMolecules(with radioSwatchesModel: RadioSwatchesModel?) { - guard let newSwatches = radioSwatchesModel?.swatches else { - swatches = nil + open func setHeight() { + guard let swatches = swatches, swatches.count > 0 else { + collectionViewHeight?.constant = 0 return } - swatches = newSwatches + // Calculate the height let collectionViewWidth = UIScreen.main.bounds.width - (2 * MFStyler.defaultHorizontalPaddingForApplicationWidth()) - let swatchesInRow = Double(floor(Double(collectionViewWidth/60.0))) - let numberOfRows = floor(Double(swatches?.count ?? 1)/swatchesInRow) + 1.0 - let height = (numberOfRows * cellSize) + (spacing * (numberOfRows-1)) + let swatchesInRow = floor(CGFloat(collectionViewWidth/(cellSize + itemSpacing))) + let numberOfRows = ceil(CGFloat(swatches.count)/swatchesInRow) + let height = (numberOfRows * cellSize) + (itemSpacing * (numberOfRows-1)) collectionViewHeight?.constant = CGFloat(height) - collectionViewHeight?.isActive = true } } @@ -115,21 +115,28 @@ extension RadioSwatches: UICollectionViewDataSource { } open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - guard let molecule = swatches?[indexPath.row], let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioSwatchItemCollectionViewCell", for: indexPath) as? RadioSwatchItem else { - return UICollectionViewCell() + guard let molecule = swatches?[indexPath.row], let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioSwatchItemCollectionViewCell", for: indexPath) as? RadioSwatchItemCollectionViewCell else { + fatalError() } - cell.set(with: molecule, nil, nil) + cell.radioSwatch.isUserInteractionEnabled = false + cell.set(with: molecule, delegateObject, nil) + cell.updateView(size ?? collectionView.bounds.width) + if molecule.selected ?? false { + collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically) + } + cell.layoutIfNeeded() return cell } } extension RadioSwatches: UICollectionViewDelegate { public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - guard let swatchItem = swatches?[indexPath.row] else { return } - swatchItem.selected = true + guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchItemCollectionViewCell else { return } + cell.radioSwatch.selectSwatch() + _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) } public func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { - guard let swatchItem = swatches?[indexPath.row] else { return } - swatchItem.selected = false + guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchItemCollectionViewCell else { return } + cell.radioSwatch.deselectSwatch() } } diff --git a/MVMCoreUI/Atomic/Atoms/RadioSwatchesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift similarity index 86% rename from MVMCoreUI/Atomic/Atoms/RadioSwatchesModel.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift index e5e0ce11..965b72f6 100644 --- a/MVMCoreUI/Atomic/Atoms/RadioSwatchesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift @@ -8,25 +8,39 @@ import Foundation -@objcMembers public class RadioSwatchesModel: MoleculeModelProtocol { +@objcMembers public class RadioSwatchesModel: MoleculeModelProtocol, FormFieldProtocol { public var backgroundColor: Color? public static var identifier: String = "radioSwatches" public var swatches: [RadioSwatchItemModel] + public var fieldKey: String? + public var groupName: String = FormValidator.defaultGroupName + public var baseValue: AnyHashable? - public init(swatches: [RadioSwatchItemModel]) { - self.swatches = swatches + /// Returns the fieldValue of the selected swatch, otherwise the text of selected swatch. + public func formFieldValue() -> AnyHashable? { + let selectedSwatch = swatches.first { (swatch) -> Bool in + return (swatch.selected ?? false) + } + return selectedSwatch?.fieldValue ?? selectedSwatch?.text } private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor case swatches + case fieldKey + case groupName } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - self.swatches = try typeContainer.decode([RadioSwatchItemModel].self, forKey: .swatches) self.backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + self.swatches = try typeContainer.decode([RadioSwatchItemModel].self, forKey: .swatches) + fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) + if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { + self.groupName = groupName + } + baseValue = formFieldValue() } public func encode(to encoder: Encoder) throws { @@ -34,10 +48,12 @@ import Foundation try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(swatches, forKey: .swatches) + try container.encodeIfPresent(fieldKey, forKey: .fieldKey) + try container.encodeIfPresent(groupName, forKey: .groupName) } } -@objcMembers public class RadioSwatchItemModel: MoleculeModelProtocol, FormFieldProtocol { +@objcMembers public class RadioSwatchItemModel: MoleculeModelProtocol { public var backgroundColor: Color? public static var identifier: String = "radioSwatchItem" public var color: Color = Color(uiColor: .mvmBlue) @@ -47,24 +63,6 @@ import Foundation public var strikethrough: Bool? = false public var fieldKey: String? public var fieldValue: String? - public var baseValue: AnyHashable? - public var groupName: String = FormValidator.defaultGroupName - - public init(color: Color, text:String, selected: Bool, enabled: Bool, strikethrough: Bool, fieldKey: String, fieldValue: String, groupName:String) { - self.color = color - self.text = text - self.selected = selected - self.fieldValue = fieldValue - self.enabled = enabled - self.strikethrough = strikethrough - self.fieldKey = fieldKey - self.groupName = groupName - baseValue = selected - } - - public func formFieldValue() -> AnyHashable? { - return selected - } private enum CodingKeys: String, CodingKey { case moleculeName @@ -74,9 +72,7 @@ import Foundation case selected case enabled case strikethrough - case fieldKey case fieldValue - case groupName } required public init(from decoder: Decoder) throws { @@ -95,12 +91,7 @@ import Foundation if let strikethrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) { self.strikethrough = strikethrough } - baseValue = self.selected - fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue) - if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { - self.groupName = groupName - } } public func encode(to encoder: Encoder) throws { @@ -112,9 +103,7 @@ import Foundation try container.encodeIfPresent(selected, forKey: .selected) try container.encodeIfPresent(enabled, forKey: .enabled) try container.encodeIfPresent(strikethrough, forKey: .strikethrough) - try container.encodeIfPresent(fieldKey, forKey: .fieldKey) try container.encodeIfPresent(fieldValue, forKey: .fieldValue) - try container.encodeIfPresent(groupName, forKey: .groupName) } } diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index ab0d5b43..1b050aca 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -70,6 +70,7 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self) MoleculeObjectMapping.shared()?.register(viewClass: RadioBoxes.self, viewModelClass: RadioBoxesModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: RadioSwatches.self, viewModelClass: RadioSwatchesModel.self) // Other Atoms MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self) From 5f125524be93872fb4bdd543a7093230547b40dd Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Tue, 14 Apr 2020 08:47:47 +0530 Subject: [PATCH 09/34] Initial commit --- MVMCoreUI.xcodeproj/project.pbxproj | 8 +++ .../Atomic/Atoms/Selectors/RadioBox.swift | 2 + MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 2 + ...ListRightVariablePriceChangeBodyText.swift | 55 +++++++++++++++++++ ...ightVariablePriceChangeBodyTextModel.swift | 52 ++++++++++++++++++ 5 files changed, 119 insertions(+) create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyTextModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 294f6188..778d8ab8 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -198,6 +198,8 @@ BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */; }; BB54C5202434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */; }; BB54C5212434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB54C51F2434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift */; }; + BB55B51D244482C1002001AD /* ListRightVariablePriceChangeBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB55B51C244482C0002001AD /* ListRightVariablePriceChangeBodyText.swift */; }; + BB55B51F244482D2002001AD /* ListRightVariablePriceChangeBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB55B51E244482D2002001AD /* ListRightVariablePriceChangeBodyTextModel.swift */; }; BB6C6AC0242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6ABE242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift */; }; BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6ABF242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift */; }; BB6C6AC824225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6AC62422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift */; }; @@ -624,6 +626,8 @@ BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsection.swift; sourceTree = ""; }; BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableButtonAllTextAndLinks.swift; sourceTree = ""; }; BB54C51F2434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableButtonAllTextAndLinksModel.swift; sourceTree = ""; }; + BB55B51C244482C0002001AD /* ListRightVariablePriceChangeBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePriceChangeBodyText.swift; sourceTree = ""; }; + BB55B51E244482D2002001AD /* ListRightVariablePriceChangeBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePriceChangeBodyTextModel.swift; sourceTree = ""; }; BB6C6ABE242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerTallModel.swift; sourceTree = ""; }; BB6C6ABF242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerTall.swift; sourceTree = ""; }; BB6C6AC62422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerShort.swift; sourceTree = ""; }; @@ -1085,6 +1089,8 @@ AA4FC2A323F4F69600E251DB /* RightVariable */ = { isa = PBXGroup; children = ( + BB55B51E244482D2002001AD /* ListRightVariablePriceChangeBodyTextModel.swift */, + BB55B51C244482C0002001AD /* ListRightVariablePriceChangeBodyText.swift */, BB54C51F2434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift */, BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */, BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */, @@ -2159,6 +2165,7 @@ 525019DE2406430800EED91C /* ListProgressBarData.swift in Sources */, D28A837F23CCA96400DFE4FC /* TabsModel.swift in Sources */, 012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */, + BB55B51F244482D2002001AD /* ListRightVariablePriceChangeBodyTextModel.swift in Sources */, D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */, D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */, 01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */, @@ -2217,6 +2224,7 @@ D22479962316AF6E003FCCF9 /* HeadlineBodyLink.swift in Sources */, D29DF2AE21E7B3A4003B2FB9 /* MFTextView.m in Sources */, 0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */, + BB55B51D244482C1002001AD /* ListRightVariablePriceChangeBodyText.swift in Sources */, 017BEB382360C6AC0024EF95 /* RadioButtonLabel.swift in Sources */, D29DF18121E69E50003B2FB9 /* MFView.m in Sources */, D28A837923C7D5BC00DFE4FC /* PageModelProtocol.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift index da762dbb..1c8527e8 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift @@ -98,6 +98,7 @@ open class RadioBox: Control { if !isEnabled { let mask = getMaskLayer() layer.mask = mask + maskLayer = mask } } @@ -108,6 +109,7 @@ open class RadioBox: Control { } @objc open func selectBox() { + isSelected = true radioBoxModel?.selected = isSelected layer.setNeedsDisplay() diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index ab0d5b43..c59bf1c7 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -138,6 +138,8 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonBodyText.self, viewModelClass: ListLeftVariableRadioButtonBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeBodyText.self, viewModelClass: ListRightVariablePriceChangeBodyTextModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTotalData.self, viewModelClass: ListRightVariableTotalDataModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTextLinkAllTextAndLinks.self, viewModelClass: ListRightVariableTextLinkAllTextAndLinksModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableButtonAllTextAndLinks.self, viewModelClass: ListRightVariableButtonAllTextAndLinksModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift new file mode 100644 index 00000000..7b4be31f --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift @@ -0,0 +1,55 @@ +// +// ListRightVariablePriceChangeBodyText.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 13/04/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +@objcMembers open class ListRightVariablePriceChangeBodyText: TableViewCell { + + //----------------------------------------------------- + // MARK: - Outlets + //----------------------------------------------------- + public var stack: Stack + public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) + public let rightLabel = Label.commonLabelB2(true) + public let arrow = Arrow(frame: .zero) + + + + // MARK: - Initializers + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading)), + (view: rightLabel, model: StackItemModel(horizontalAlignment:.fill)), + (view: arrow, model: StackItemModel(horizontalAlignment:.fill))], + axis: .horizontal) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + //----------------------------------------------------- + // MARK: - View Lifecycle + //----------------------------------------------------- + override open func setupView() { + super.setupView() + addMolecule(stack) + stack.restack() + } + + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListRightVariablePriceChangeBodyTextModel else { return } + eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + rightLabel.set(with: model.rightLabel, delegateObject, additionalData) + arrow.set(with: model.arrow, delegateObject, additionalData) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 120 + } +} diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyTextModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyTextModel.swift new file mode 100644 index 00000000..3855ffb8 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyTextModel.swift @@ -0,0 +1,52 @@ +// +// ListRightVariablePriceChangeBodyTextModel.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 13/04/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +public class ListRightVariablePriceChangeBodyTextModel: ListItemModel, MoleculeModelProtocol { + public static var identifier: String = "listRVArwBdy" + public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel + public var rightLabel: LabelModel + public var arrow: ArrowModel + + + + public init(eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel,rightLabel: LabelModel,arrow: ArrowModel) { + self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink + self.rightLabel = rightLabel + self.arrow = arrow + super.init() + } + + + + private enum CodingKeys: String, CodingKey { + case moleculeName + case eyebrowHeadlineBodyLink + case rightLabel + case arrow + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink) + rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) + arrow = try typeContainer.decode(ArrowModel.self, forKey: .arrow) + + 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(eyebrowHeadlineBodyLink, forKey: .eyebrowHeadlineBodyLink) + try container.encode(rightLabel, forKey: .rightLabel) + try container.encode(arrow, forKey: .arrow) + + } +} From b348bdfdaba8ea41fcaada83ae33764e1de9c273 Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Tue, 14 Apr 2020 10:50:04 +0530 Subject: [PATCH 10/34] border related issues fixed --- MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift | 6 ++++-- MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift | 4 ++++ MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift index da762dbb..458acfdf 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift @@ -39,7 +39,7 @@ open class RadioBox: Control { super.setupView() layer.delegate = self - layer.borderColor = UIColor.black.cgColor + layer.borderColor = UIColor.mfGet(forHex: "#747676").cgColor layer.borderWidth = 1 label.numberOfLines = 1 @@ -77,11 +77,12 @@ open class RadioBox: Control { // Draw the strikethrough strikeLayer?.removeFromSuperlayer() if isOutOfStock { - let line = getStrikeThrough(color: .black, thickness: 1) + let line = getStrikeThrough(color: isSelected ?.black:UIColor.mfGet(forHex: "#747676") , thickness: 1) layer.addSublayer(line) strikeLayer = line } + // Draw the border borderLayer?.removeFromSuperlayer() if isSelected { @@ -98,6 +99,7 @@ open class RadioBox: Control { if !isEnabled { let mask = getMaskLayer() layer.mask = mask + maskLayer = mask } } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift index 6fe66bc2..d3997323 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift @@ -111,6 +111,10 @@ extension RadioBoxes: UICollectionViewDataSource { open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return boxes?.count ?? 0 } + public func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { + guard let molecule = boxes?[indexPath.row] else {return true } + return molecule.enabled + } open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let molecule = boxes?[indexPath.row], diff --git a/MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift index 826759a7..b8b5321d 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift @@ -276,7 +276,7 @@ import UIKit let fallbackImageName = customFallbackImage ?? MVMCoreUIUtility.localizedImageName("fallback") if let format = format, format.lowercased().contains("gif") { // Gifs aren't supported by default and need special handling - MVMCoreCache.shared()?.getGif(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, localBundle: localBundle, completionHandler: finishedLoadingBlock) + MVMCoreCache.shared()?.getGif(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, completionHandler: finishedLoadingBlock) } else { MVMCoreCache.shared()?.getImage(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, localBundle: localBundle, completionHandler: finishedLoadingBlock) } From c51dcfc5741706f6d5a4d28fd6f4c326fd18e30a Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Tue, 14 Apr 2020 14:13:04 +0530 Subject: [PATCH 11/34] arrow changes implemented --- .../ListRightVariablePriceChangeBodyText.swift | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift index 7b4be31f..07e74886 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift @@ -16,14 +16,15 @@ import Foundation public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) public let rightLabel = Label.commonLabelB2(true) public let arrow = Arrow(frame: .zero) - - + let arrowAndrightLabelStack: Stack // MARK: - Initializers public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + arrowAndrightLabelStack = Stack.createStack(with: [(view: arrow, model: StackItemModel(horizontalAlignment: .fill)), + (view: rightLabel, model: StackItemModel(horizontalAlignment: .leading))], + axis: .horizontal, spacing: 4) stack = Stack.createStack(with: [(view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading)), - (view: rightLabel, model: StackItemModel(horizontalAlignment:.fill)), - (view: arrow, model: StackItemModel(horizontalAlignment:.fill))], + (view: arrowAndrightLabelStack, model: StackItemModel(verticalAlignment: .top))], axis: .horizontal) super.init(style: style, reuseIdentifier: reuseIdentifier) } @@ -37,8 +38,11 @@ import Foundation //----------------------------------------------------- override open func setupView() { super.setupView() + arrow.pinHeightAndWidth() addMolecule(stack) stack.restack() + arrowAndrightLabelStack.restack() + } open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { @@ -52,4 +56,8 @@ import Foundation open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 120 } + open override func reset() { + super.reset() + rightLabel.styleB2(true) + } } From 9c29916606bf468d49d7655645fda2958be903d6 Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Tue, 14 Apr 2020 14:20:29 +0530 Subject: [PATCH 12/34] number of columns variable added --- MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift | 3 ++- MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift index d3997323..b766e461 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift @@ -15,6 +15,7 @@ open class RadioBoxes: View { private let boxWidth: CGFloat = 151.0 private let boxHeight: CGFloat = 64.0 private let itemSpacing: CGFloat = 8.0 + private var numberOfColumns: CGFloat = 2.0 private var delegateObject: MVMCoreUIDelegateObject? @@ -94,7 +95,7 @@ open class RadioBoxes: View { } // Calculate the height - let rows = ceil(CGFloat(boxes.count) / 2.0) + let rows = ceil(CGFloat(boxes.count) / numberOfColumns) let height = (rows * boxHeight) + ((rows - 1) * itemSpacing) collectionViewHeight?.constant = height } diff --git a/MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift index b8b5321d..826759a7 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift @@ -276,7 +276,7 @@ import UIKit let fallbackImageName = customFallbackImage ?? MVMCoreUIUtility.localizedImageName("fallback") if let format = format, format.lowercased().contains("gif") { // Gifs aren't supported by default and need special handling - MVMCoreCache.shared()?.getGif(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, completionHandler: finishedLoadingBlock) + MVMCoreCache.shared()?.getGif(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, localBundle: localBundle, completionHandler: finishedLoadingBlock) } else { MVMCoreCache.shared()?.getImage(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, localBundle: localBundle, completionHandler: finishedLoadingBlock) } From 04a148aa72daec8bc425e5839d9f2c1114513ffe Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Tue, 14 Apr 2020 14:46:21 +0530 Subject: [PATCH 13/34] MFloadimageview changes reverted --- MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift index b8b5321d..826759a7 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/MFLoadImageView.swift @@ -276,7 +276,7 @@ import UIKit let fallbackImageName = customFallbackImage ?? MVMCoreUIUtility.localizedImageName("fallback") if let format = format, format.lowercased().contains("gif") { // Gifs aren't supported by default and need special handling - MVMCoreCache.shared()?.getGif(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, completionHandler: finishedLoadingBlock) + MVMCoreCache.shared()?.getGif(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, localBundle: localBundle, completionHandler: finishedLoadingBlock) } else { MVMCoreCache.shared()?.getImage(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, localBundle: localBundle, completionHandler: finishedLoadingBlock) } From 98ff848b33a0e73247f7c6e7e3c5093d6aac1861 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Tue, 14 Apr 2020 15:18:29 +0530 Subject: [PATCH 14/34] Added stroke color changes for selected and not selected. --- MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift | 8 ++++---- .../Selectors/RadioSwatchItemCollectionViewCell.swift | 1 - MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift | 5 +++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift index f6054ebb..2b5c05f3 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift @@ -71,7 +71,7 @@ open class RadioSwatchItem: Control { //Draw the strikethrough strikeLayer?.removeFromSuperlayer() if isOutOfStock { - let line = getStrikeThrough(color: UIColor.mvmCoolGray6, thickness: 1) + let line = getStrikeThrough(color: UIColor.mvmBlack, thickness: 1) layer.addSublayer(line) strikeLayer = line } @@ -79,7 +79,7 @@ open class RadioSwatchItem: Control { //Draw the selected layer selectedLayer?.removeFromSuperlayer() if isSelected { - let outerCircle = getSelectedLayer(color: UIColor.black, thickness: 1) + let outerCircle = getSelectedLayer(color: UIColor.mvmBlack, thickness: 1) layer.addSublayer(outerCircle) selectedLayer = outerCircle bottomText.isHidden = false @@ -121,7 +121,7 @@ open class RadioSwatchItem: Control { circle.fillColor = fillColor.cgColor circle.opacity = 1.0 circle.lineWidth = thickness - circle.strokeColor = isEnabled ? color.cgColor : UIColor.mvmCoolGray6.cgColor + circle.strokeColor = isSelected ? color.cgColor : UIColor.mvmCoolGray6.cgColor let circlePath = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)) circle.path = circlePath.cgPath @@ -134,7 +134,7 @@ open class RadioSwatchItem: Control { strikeThrough.fillColor = nil strikeThrough.opacity = 1.0 strikeThrough.lineWidth = thickness - strikeThrough.strokeColor = color.cgColor + strikeThrough.strokeColor = isSelected ? color.cgColor : UIColor.mvmCoolGray6.cgColor let linePath = UIBezierPath() linePath.move(to: CGPoint(x: 12, y: 30)) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift index b274d28d..3d3100a8 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift @@ -19,6 +19,5 @@ open class RadioSwatchItemCollectionViewCell: CollectionViewCell { open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let model = model as? RadioSwatchItemModel else { return } radioSwatch.set(with: model, delegateObject, additionalData) - self.isUserInteractionEnabled = model.enabled ?? true } } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift index d73c749a..ed16fc39 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift @@ -114,6 +114,11 @@ extension RadioSwatches: UICollectionViewDataSource { return swatches?.count ?? 0 } + public func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { + guard let molecule = swatches?[indexPath.row] else {return true } + return molecule.enabled ?? true + } + open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let molecule = swatches?[indexPath.row], let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioSwatchItemCollectionViewCell", for: indexPath) as? RadioSwatchItemCollectionViewCell else { fatalError() From f138c0a256f55798ffb1725efe8dec9f0ec04eb2 Mon Sep 17 00:00:00 2001 From: Kruthika KP <> Date: Tue, 14 Apr 2020 16:30:13 +0530 Subject: [PATCH 15/34] 18965 - List - Right Variable - Price Change - All Text & Links - Initial commit --- MVMCoreUI.xcodeproj/project.pbxproj | 8 +++ MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 3 +- ...htVariablePriceChangeAllTextAndLinks.swift | 69 +++++++++++++++++++ ...iablePriceChangeAllTextAndLinksModel.swift | 55 +++++++++++++++ 4 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinksModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 294f6188..07fe171e 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -139,6 +139,8 @@ 8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */; }; 8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D4687E1242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift */; }; 8D4687E4242E2DF300802879 /* ListFourColumnDataUsageListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D4687E3242E2DF300802879 /* ListFourColumnDataUsageListItem.swift */; }; + 8D8067D12444472F00203BE8 /* ListRightVariablePriceChangeAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D8067D02444472F00203BE8 /* ListRightVariablePriceChangeAllTextAndLinksModel.swift */; }; + 8D8067D32444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D8067D22444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift */; }; 8DD1E36E243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DD1E36D243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift */; }; 8DD1E370243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DD1E36F243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift */; }; 8DEFA95C243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DEFA95B243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift */; }; @@ -566,6 +568,8 @@ 8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextAllTextAndLinksModel.swift; sourceTree = ""; }; 8D4687E1242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageListItemModel.swift; sourceTree = ""; }; 8D4687E3242E2DF300802879 /* ListFourColumnDataUsageListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageListItem.swift; sourceTree = ""; }; + 8D8067D02444472F00203BE8 /* ListRightVariablePriceChangeAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePriceChangeAllTextAndLinksModel.swift; sourceTree = ""; }; + 8D8067D22444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariablePriceChangeAllTextAndLinks.swift; sourceTree = ""; }; 8DD1E36D243B3CFB00D8F2DF /* ListThreeColumnInternationalDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnInternationalDataModel.swift; sourceTree = ""; }; 8DD1E36F243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnInternationalData.swift; sourceTree = ""; }; 8DEFA95B243DAC20000D27E5 /* ListThreeColumnDataUsageDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnDataUsageDividerModel.swift; sourceTree = ""; }; @@ -1093,6 +1097,8 @@ AA11A41E23F15D3100D7962F /* ListRightVariablePayments.swift */, 8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */, 8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */, + 8D8067D02444472F00203BE8 /* ListRightVariablePriceChangeAllTextAndLinksModel.swift */, + 8D8067D22444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift */, C7F8012223E846C300396FBD /* ListRVWheelModel.swift */, C7F8012023E8303200396FBD /* ListRVWheel.swift */, ); @@ -2085,6 +2091,7 @@ 942C378C2412F4FA0066E45E /* ModalMoleculeListTemplate.swift in Sources */, BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */, 012A88C8238DB02000FE3DA1 /* MoleculeDelegateProtocol.swift in Sources */, + 8D8067D12444472F00203BE8 /* ListRightVariablePriceChangeAllTextAndLinksModel.swift in Sources */, 0A7EF86123D8AC2500B2AAD1 /* DigitEntryFieldModel.swift in Sources */, DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */, D224798C231450C8003FCCF9 /* HeadlineBodyToggle.swift in Sources */, @@ -2210,6 +2217,7 @@ 0A6682AC243531C300AD3CA1 /* Padding.swift in Sources */, AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */, 942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */, + 8D8067D32444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift in Sources */, 8D4687E4242E2DF300802879 /* ListFourColumnDataUsageListItem.swift in Sources */, 01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */, 0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index ab0d5b43..2886f49d 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -148,7 +148,8 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnPriceDescription.self, viewModelClass: ListTwoColumnPriceDescriptionModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnInternationalData.self, viewModelClass: ListThreeColumnInternationalDataModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self) - + MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeAllTextAndLinks.self, viewModelClass: ListRightVariablePriceChangeAllTextAndLinksModel.self) + // Designed Section Dividers MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnPlanDataDivider.self, viewModelClass: ListThreeColumnPlanDataDividerModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift new file mode 100644 index 00000000..6d179922 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift @@ -0,0 +1,69 @@ +// +// ListRightVariablePriceChangeAllTextAndLinks.swift +// MVMCoreUI +// +// Created by Kruthika KP on 13/04/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers public class ListRightVariablePriceChangeAllTextAndLinks: TableViewCell { + + //----------------------------------------------------- + // MARK: - Outlets + //----------------------------------------------------- + open var stack: Stack + public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) + public let rightLabel = Label.commonLabelB2(true) + public let arrow = Arrow(frame: .zero) + public let arrowAndLabel2Stack: Stack + + //----------------------------------------------------- + // MARK: - Initializers + //----------------------------------------------------- + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + arrowAndLabel2Stack = Stack.createStack(with: [(view: arrow, model: StackItemModel(horizontalAlignment: .trailing)), + (view: rightLabel, model: StackItemModel(horizontalAlignment: .fill))], + axis: .horizontal, spacing: 6) + rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal) + rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal) + stack = Stack.createStack(with: [(view: eyebrowHeadlineBodyLink, model: StackItemModel(percent: 70, horizontalAlignment: .leading)), + (view: arrowAndLabel2Stack, model: StackItemModel(percent: 30, horizontalAlignment: .fill, verticalAlignment: .top))], + axis: .horizontal) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + //----------------------------------------------------- + // MARK: - View Lifecycle + //----------------------------------------------------- + override open func setupView() { + super.setupView() + addMolecule(stack) + arrow.pinHeightAndWidth() + arrowAndLabel2Stack.restack() + stack.restack() + } + + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListRightVariablePriceChangeAllTextAndLinksModel else { return } + eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + rightLabel.set(with: model.rightLabel, delegateObject, additionalData) + arrow.set(with: model.arrow, delegateObject, additionalData) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 121 + } + + open override func reset() { + super.reset() + rightLabel.styleB2(true) + } +} + diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinksModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinksModel.swift new file mode 100644 index 00000000..c0f749e2 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinksModel.swift @@ -0,0 +1,55 @@ +// +// ListRightVariablePriceChangeAllTextAndLinksModel.swift +// MVMCoreUI +// +// Created by Kruthika KP on 13/04/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class ListRightVariablePriceChangeAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol { + + public static var identifier: String = "listRVArwAll" + public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel + public var rightLabel: LabelModel + public var arrow: ArrowModel + + public init(eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel, rightLabel: LabelModel, arrow: ArrowModel) { + self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink + self.rightLabel = rightLabel + self.arrow = arrow + super.init() + } + + override public func setDefaults() { + super.setDefaults() + if let headline = eyebrowHeadlineBodyLink.headline { + headline.hero = 0 + } + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case eyebrowHeadlineBodyLink + case rightLabel + case arrow + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink) + rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) + arrow = try typeContainer.decode(ArrowModel.self, forKey: .arrow) + 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(eyebrowHeadlineBodyLink, forKey: .eyebrowHeadlineBodyLink) + try container.encode(rightLabel, forKey: .rightLabel) + try container.encode(arrow, forKey: .arrow) + } +} From 73403b894875cdc7441bc68147e7849506e6923c Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Wed, 15 Apr 2020 08:53:28 +0530 Subject: [PATCH 16/34] alignment changes updated --- .../RightVariable/ListRightVariablePriceChangeBodyText.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift index 07e74886..fd29f10c 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift @@ -23,8 +23,8 @@ import Foundation arrowAndrightLabelStack = Stack.createStack(with: [(view: arrow, model: StackItemModel(horizontalAlignment: .fill)), (view: rightLabel, model: StackItemModel(horizontalAlignment: .leading))], axis: .horizontal, spacing: 4) - stack = Stack.createStack(with: [(view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading)), - (view: arrowAndrightLabelStack, model: StackItemModel(verticalAlignment: .top))], + stack = Stack.createStack(with: [(view: eyebrowHeadlineBodyLink, model: StackItemModel(percent:70,horizontalAlignment: .leading)), + (view: arrowAndrightLabelStack, model: StackItemModel(percent:30,horizontalAlignment: .trailing,verticalAlignment: .top))], axis: .horizontal) super.init(style: style, reuseIdentifier: reuseIdentifier) } From 594a45894e5899aec606206258fbcf14146c9b86 Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Wed, 15 Apr 2020 15:57:57 +0530 Subject: [PATCH 17/34] updated as per confluence --- ...ListRightVariablePriceChangeBodyText.swift | 26 +++++++++---------- ...ightVariablePriceChangeBodyTextModel.swift | 6 ----- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift index fd29f10c..c62a7eaf 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift @@ -13,18 +13,18 @@ import Foundation // MARK: - Outlets //----------------------------------------------------- public var stack: Stack - public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) + public let headlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) public let rightLabel = Label.commonLabelB2(true) public let arrow = Arrow(frame: .zero) - let arrowAndrightLabelStack: Stack + let arrowAndRightLabelStack: Stack // MARK: - Initializers public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - arrowAndrightLabelStack = Stack.createStack(with: [(view: arrow, model: StackItemModel(horizontalAlignment: .fill)), - (view: rightLabel, model: StackItemModel(horizontalAlignment: .leading))], - axis: .horizontal, spacing: 4) - stack = Stack.createStack(with: [(view: eyebrowHeadlineBodyLink, model: StackItemModel(percent:70,horizontalAlignment: .leading)), - (view: arrowAndrightLabelStack, model: StackItemModel(percent:30,horizontalAlignment: .trailing,verticalAlignment: .top))], + arrowAndRightLabelStack = Stack.createStack(with: [(view: arrow, model: StackItemModel(horizontalAlignment: .fill)), + (view: rightLabel, model: StackItemModel(horizontalAlignment: .leading))], + axis: .horizontal, spacing: 6) + stack = Stack.createStack(with: [(view: headlineBodyLink, model: StackItemModel(percent:70,horizontalAlignment: .leading)), + (view: arrowAndRightLabelStack, model: StackItemModel(percent:30,horizontalAlignment: .trailing,verticalAlignment: .top))], axis: .horizontal) super.init(style: style, reuseIdentifier: reuseIdentifier) } @@ -41,14 +41,13 @@ import Foundation arrow.pinHeightAndWidth() addMolecule(stack) stack.restack() - arrowAndrightLabelStack.restack() - + arrowAndRightLabelStack.restack() } open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.set(with: model, delegateObject, additionalData) guard let model = model as? ListRightVariablePriceChangeBodyTextModel else { return } - eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + headlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) rightLabel.set(with: model.rightLabel, delegateObject, additionalData) arrow.set(with: model.arrow, delegateObject, additionalData) } @@ -56,8 +55,9 @@ import Foundation open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 120 } + open override func reset() { - super.reset() - rightLabel.styleB2(true) - } + super.reset() + rightLabel.styleB2(true) + } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyTextModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyTextModel.swift index 3855ffb8..e2d90eb7 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyTextModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyTextModel.swift @@ -13,8 +13,6 @@ public class ListRightVariablePriceChangeBodyTextModel: ListItemModel, MoleculeM public var rightLabel: LabelModel public var arrow: ArrowModel - - public init(eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel,rightLabel: LabelModel,arrow: ArrowModel) { self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink self.rightLabel = rightLabel @@ -22,8 +20,6 @@ public class ListRightVariablePriceChangeBodyTextModel: ListItemModel, MoleculeM super.init() } - - private enum CodingKeys: String, CodingKey { case moleculeName case eyebrowHeadlineBodyLink @@ -36,7 +32,6 @@ public class ListRightVariablePriceChangeBodyTextModel: ListItemModel, MoleculeM eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink) rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) arrow = try typeContainer.decode(ArrowModel.self, forKey: .arrow) - try super.init(from: decoder) } @@ -47,6 +42,5 @@ public class ListRightVariablePriceChangeBodyTextModel: ListItemModel, MoleculeM try container.encode(eyebrowHeadlineBodyLink, forKey: .eyebrowHeadlineBodyLink) try container.encode(rightLabel, forKey: .rightLabel) try container.encode(arrow, forKey: .arrow) - } } From 7b3e22826ca0f7f7cf36b21d0f0cb2418eb1df29 Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Wed, 15 Apr 2020 16:10:39 +0530 Subject: [PATCH 18/34] number of columns per row updated --- MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift index b766e461..9fa451f6 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift @@ -103,7 +103,7 @@ open class RadioBoxes: View { extension RadioBoxes: UICollectionViewDelegateFlowLayout { open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { - let itemWidth: CGFloat = (collectionView.bounds.width - itemSpacing) / 2 + let itemWidth: CGFloat = (collectionView.bounds.width - itemSpacing) / numberOfColumns return CGSize(width: itemWidth, height: boxHeight) } } From 2d489e1ef48deba8e767bf13154ec2338e157cdc Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 15 Apr 2020 10:38:55 -0400 Subject: [PATCH 19/34] hot fix --- MVMCoreUI/BaseControllers/ViewController.swift | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index eb4be908..a49dfad3 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -266,9 +266,7 @@ import UIKit } // Handle data for first load. Dispatched to allow subclasses to finish their view did load implementations. - DispatchQueue.main.async { - self.handleNewDataAndUpdateUI() - } + self.handleNewDataAndUpdateUI() } open override func viewDidLayoutSubviews() { @@ -292,8 +290,10 @@ import UIKit open override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - // Update the navigation bar ui when view is appearing - setNavigationController() + // Update the navigation bar ui when view is appearing. Can remove check in the future, see viewControllerReady + if manager == nil { + setNavigationController() + } } open override func viewDidAppear(_ animated: Bool) { @@ -326,6 +326,10 @@ import UIKit // MARK: - MVMCoreViewManagerViewControllerProtocol open func viewControllerReady(inManager manager: UIViewController & MVMCoreViewManagerProtocol) { + // TODO: This check and set aren't technically needed anymore. The one in viewwillappear should be enough. However, there is a timing issue with the manager where the screen lays out before the menu shows, so the screen grows off the screen. Can fix in the future. + if let _ = self.view { + setNavigationController() + } // Janky way to track current page. MVMCoreUISession.sharedGlobal()?.currentPageType = pageType MVMCoreUILoggingHandler.shared()?.defaultLogPageState(forController: self) From 5ca03674c2f8dd348172432f4400f5a12d2b69b7 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 15 Apr 2020 12:59:57 -0400 Subject: [PATCH 20/34] clean color code, move function --- MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift | 5 +++-- MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift index 458acfdf..ff3452fb 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift @@ -39,7 +39,7 @@ open class RadioBox: Control { super.setupView() layer.delegate = self - layer.borderColor = UIColor.mfGet(forHex: "#747676").cgColor + layer.borderColor = UIColor.mvmCoolGray6.cgColor layer.borderWidth = 1 label.numberOfLines = 1 @@ -77,7 +77,7 @@ open class RadioBox: Control { // Draw the strikethrough strikeLayer?.removeFromSuperlayer() if isOutOfStock { - let line = getStrikeThrough(color: isSelected ?.black:UIColor.mfGet(forHex: "#747676") , thickness: 1) + let line = getStrikeThrough(color: isSelected ? .black : .mvmCoolGray6, thickness: 1) layer.addSublayer(line) strikeLayer = line } @@ -110,6 +110,7 @@ open class RadioBox: Control { } @objc open func selectBox() { + guard isEnabled else { return } isSelected = true radioBoxModel?.selected = isSelected layer.setNeedsDisplay() diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift index 9fa451f6..4b42e9a8 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift @@ -112,10 +112,6 @@ extension RadioBoxes: UICollectionViewDataSource { open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return boxes?.count ?? 0 } - public func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { - guard let molecule = boxes?[indexPath.row] else {return true } - return molecule.enabled - } open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let molecule = boxes?[indexPath.row], @@ -134,6 +130,11 @@ extension RadioBoxes: UICollectionViewDataSource { } extension RadioBoxes: UICollectionViewDelegate { + public func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { + guard let molecule = boxes?[indexPath.row] else { return false } + return molecule.enabled + } + public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return } cell.radioBox.selectBox() From 14b1e66ffe0908eff8c5f03ff32a9ce719c1538d Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Wed, 15 Apr 2020 18:20:04 -0400 Subject: [PATCH 21/34] button will set groupname only when validation is required --- MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift index 178c309e..abdc1242 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift @@ -32,7 +32,7 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupW public var disabledFillColor: Color? public var disabledTextColor: Color? public var disabledBorderColor: Color? - public var groupName: String = FormValidator.defaultGroupName + public var groupName: String = "" public func setValidity(_ valid: Bool, group: FormGroupRule) { enabled = valid From e1894bd74b9fe2f7307fb5b0fc6ac48fb1f34323 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Thu, 16 Apr 2020 11:26:56 +0530 Subject: [PATCH 22/34] moved function, clean code --- MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift | 7 ++++--- MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift | 10 +++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift index 2b5c05f3..9117aee8 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift @@ -64,14 +64,14 @@ open class RadioSwatchItem: Control { open override func draw(_ layer: CALayer, in ctx: CGContext) { //Draw the swatch circleLayer?.removeFromSuperlayer() - let circle = getCircle(color: UIColor.mvmBlack, thickness: 1) + let circle = getCircle(color: .mvmBlack, thickness: 1) layer.addSublayer(circle) circleLayer = circle //Draw the strikethrough strikeLayer?.removeFromSuperlayer() if isOutOfStock { - let line = getStrikeThrough(color: UIColor.mvmBlack, thickness: 1) + let line = getStrikeThrough(color: .mvmBlack, thickness: 1) layer.addSublayer(line) strikeLayer = line } @@ -79,7 +79,7 @@ open class RadioSwatchItem: Control { //Draw the selected layer selectedLayer?.removeFromSuperlayer() if isSelected { - let outerCircle = getSelectedLayer(color: UIColor.mvmBlack, thickness: 1) + let outerCircle = getSelectedLayer(color: .mvmBlack, thickness: 1) layer.addSublayer(outerCircle) selectedLayer = outerCircle bottomText.isHidden = false @@ -104,6 +104,7 @@ open class RadioSwatchItem: Control { } @objc open func selectSwatch() { + guard isEnabled else { return } isSelected = true radioSwatchModel?.selected = isSelected layer.setNeedsDisplay() diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift index ed16fc39..2811da69 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift @@ -114,11 +114,6 @@ extension RadioSwatches: UICollectionViewDataSource { return swatches?.count ?? 0 } - public func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { - guard let molecule = swatches?[indexPath.row] else {return true } - return molecule.enabled ?? true - } - open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let molecule = swatches?[indexPath.row], let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioSwatchItemCollectionViewCell", for: indexPath) as? RadioSwatchItemCollectionViewCell else { fatalError() @@ -135,6 +130,11 @@ extension RadioSwatches: UICollectionViewDataSource { } extension RadioSwatches: UICollectionViewDelegate { + public func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { + guard let molecule = swatches?[indexPath.row] else {return true } + return molecule.enabled ?? true + } + public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchItemCollectionViewCell else { return } cell.radioSwatch.selectSwatch() From e4dc439d1cce72e81ba3c5c6d4329ada08b0df59 Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Thu, 16 Apr 2020 15:45:24 +0530 Subject: [PATCH 23/34] updated Code as per confluence page color changes --- MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift | 6 +++++- MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift | 4 ++-- MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift | 6 +++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift index ff3452fb..e408b50f 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift @@ -69,6 +69,10 @@ open class RadioBox: Control { subTextLabel.text = model.subText isOutOfStock = model.strikethrough subTextLabelHeightConstraint?.isActive = (subTextLabel.text?.count ?? 0) == 0 + if let boxesModel = additionalData?["radioboxesmodel"] as? RadioBoxesModel{ + backgroundColor = model.backgroundColor?.uiColor ?? (boxesModel.backgroundColor?.uiColor ?? UIColor.white) + accentColor = model.selectedAccentColor?.uiColor ?? (boxesModel.selectedAccentColor?.uiColor ?? UIColor.mvmRed) + } } // MARK: - State Handling @@ -134,7 +138,7 @@ open class RadioBox: Control { let topLineLayer = CAShapeLayer() topLineLayer.fillColor = nil - topLineLayer.strokeColor = UIColor.mvmRed.cgColor + topLineLayer.strokeColor = accentColor.cgColor topLineLayer.lineWidth = 4 topLineLayer.path = topLinePath.cgPath layer.addSublayer(topLineLayer) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift index b2a23c6a..fe47ac29 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift @@ -11,8 +11,8 @@ import Foundation public static var identifier: String = "radioBox" public var text: String public var subText: String? - public var backgroundColor: Color? = Color(uiColor: .white) - public var selectedAccentColor = Color(uiColor: .mvmRed) + public var backgroundColor: Color? + public var selectedAccentColor: Color? public var selected: Bool = false public var enabled: Bool = true public var strikethrough: Bool = false diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift index 4b42e9a8..8d05adac 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift @@ -16,6 +16,8 @@ open class RadioBoxes: View { private let boxHeight: CGFloat = 64.0 private let itemSpacing: CGFloat = 8.0 private var numberOfColumns: CGFloat = 2.0 + private var radioBoxesmodel: RadioBoxesModel! + private var delegateObject: MVMCoreUIDelegateObject? @@ -48,6 +50,7 @@ open class RadioBoxes: View { self.delegateObject = delegateObject guard let radioBoxesModel = model as? RadioBoxesModel else { return } + radioBoxesmodel = radioBoxesModel boxes = radioBoxesModel.boxes FormValidator.setupValidation(for: radioBoxesModel, delegate: delegateObject?.formHolderDelegate) @@ -118,8 +121,9 @@ extension RadioBoxes: UICollectionViewDataSource { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioBoxCollectionViewCell", for: indexPath) as? RadioBoxCollectionViewCell else { fatalError() } + let additionalData: [AnyHashable : RadioBoxesModel] = ["radioboxesmodel":radioBoxesmodel] cell.radioBox.isUserInteractionEnabled = false - cell.set(with: molecule, delegateObject, nil) + cell.set(with: molecule, delegateObject, additionalData) cell.updateView(size ?? collectionView.bounds.width) if molecule.selected { collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically) From c830c388dea8c7114f23ada0fc0c79503182cd7e Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Thu, 16 Apr 2020 16:06:04 +0530 Subject: [PATCH 24/34] model keys Updated --- MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift | 6 +++--- MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift index 8d05adac..61449d78 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift @@ -16,7 +16,7 @@ open class RadioBoxes: View { private let boxHeight: CGFloat = 64.0 private let itemSpacing: CGFloat = 8.0 private var numberOfColumns: CGFloat = 2.0 - private var radioBoxesmodel: RadioBoxesModel! + private var radioBoxesModel: RadioBoxesModel! private var delegateObject: MVMCoreUIDelegateObject? @@ -50,7 +50,7 @@ open class RadioBoxes: View { self.delegateObject = delegateObject guard let radioBoxesModel = model as? RadioBoxesModel else { return } - radioBoxesmodel = radioBoxesModel + self.radioBoxesModel = radioBoxesModel boxes = radioBoxesModel.boxes FormValidator.setupValidation(for: radioBoxesModel, delegate: delegateObject?.formHolderDelegate) @@ -121,7 +121,7 @@ extension RadioBoxes: UICollectionViewDataSource { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioBoxCollectionViewCell", for: indexPath) as? RadioBoxCollectionViewCell else { fatalError() } - let additionalData: [AnyHashable : RadioBoxesModel] = ["radioboxesmodel":radioBoxesmodel] + let additionalData: [AnyHashable : RadioBoxesModel] = ["radioboxesmodel":radioBoxesModel] cell.radioBox.isUserInteractionEnabled = false cell.set(with: molecule, delegateObject, additionalData) cell.updateView(size ?? collectionView.bounds.width) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift index 28c4fab5..55c29e35 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift @@ -27,7 +27,7 @@ import Foundation private enum CodingKeys: String, CodingKey { case moleculeName case selectedAccentColor - case backgroundColor + case backgroundColor = "boxesColor" case boxes case fieldKey case groupName From ca0f527c7b1d9d1484208e7630155b5ca861405b Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 16 Apr 2020 13:46:25 -0400 Subject: [PATCH 25/34] Code cleanup --- .../Atomic/Atoms/Selectors/RadioBox.swift | 13 ++++++++---- .../RadioBoxCollectionViewCell.swift | 7 ++++++- .../Atoms/Selectors/RadioBoxModel.swift | 10 +++------ .../Atomic/Atoms/Selectors/RadioBoxes.swift | 21 ++++++++++++------- .../Atoms/Selectors/RadioBoxesModel.swift | 7 +++++-- 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift index e408b50f..785d6ae6 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift @@ -60,7 +60,7 @@ open class RadioBox: Control { // MARK: - MoleculeViewProtocol - public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) guard let model = model as? RadioBoxModel else { return } isSelected = model.selected @@ -69,12 +69,17 @@ open class RadioBox: Control { subTextLabel.text = model.subText isOutOfStock = model.strikethrough subTextLabelHeightConstraint?.isActive = (subTextLabel.text?.count ?? 0) == 0 - if let boxesModel = additionalData?["radioboxesmodel"] as? RadioBoxesModel{ - backgroundColor = model.backgroundColor?.uiColor ?? (boxesModel.backgroundColor?.uiColor ?? UIColor.white) - accentColor = model.selectedAccentColor?.uiColor ?? (boxesModel.selectedAccentColor?.uiColor ?? UIColor.mvmRed) + if let color = model.selectedAccentColor?.uiColor { + accentColor = color } } + open override func reset() { + super.reset() + backgroundColor = .white + accentColor = .mvmRed + } + // MARK: - State Handling open override func draw(_ layer: CALayer, in ctx: CGContext) { diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxCollectionViewCell.swift index c90b5e92..c6f5474e 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxCollectionViewCell.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxCollectionViewCell.swift @@ -8,7 +8,12 @@ import Foundation open class RadioBoxCollectionViewCell: CollectionViewCell { - let radioBox = RadioBox() + public let radioBox = RadioBox() + + open override func reset() { + super.reset() + backgroundColor = .clear + } open override func setupView() { super.setupView() diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift index fe47ac29..986eefac 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift @@ -34,12 +34,8 @@ import Foundation let typeContainer = try decoder.container(keyedBy: CodingKeys.self) text = try typeContainer.decode(String.self, forKey: .text) subText = try typeContainer.decodeIfPresent(String.self, forKey: .subText) - if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor) { - selectedAccentColor = color - } - if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) { - backgroundColor = color - } + selectedAccentColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) if let isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) { selected = isSelected } @@ -58,7 +54,7 @@ import Foundation try container.encode(moleculeName, forKey: .moleculeName) try container.encode(text, forKey: .text) try container.encodeIfPresent(subText, forKey: .subText) - try container.encode(selectedAccentColor, forKey: .selectedAccentColor) + try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(selected, forKey: .selected) try container.encode(enabled, forKey: .enabled) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift index 61449d78..ef648f06 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift @@ -18,7 +18,6 @@ open class RadioBoxes: View { private var numberOfColumns: CGFloat = 2.0 private var radioBoxesModel: RadioBoxesModel! - private var delegateObject: MVMCoreUIDelegateObject? /// The models for the molecules. @@ -45,7 +44,7 @@ open class RadioBoxes: View { } // MARK: - MoleculeViewProtocol - public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) self.delegateObject = delegateObject @@ -121,9 +120,17 @@ extension RadioBoxes: UICollectionViewDataSource { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioBoxCollectionViewCell", for: indexPath) as? RadioBoxCollectionViewCell else { fatalError() } - let additionalData: [AnyHashable : RadioBoxesModel] = ["radioboxesmodel":radioBoxesModel] + cell.reset() cell.radioBox.isUserInteractionEnabled = false - cell.set(with: molecule, delegateObject, additionalData) + + if let color = radioBoxesModel?.boxesColor { + cell.radioBox.backgroundColor = color.uiColor + } + if let color = radioBoxesModel?.selectedAccentColor { + cell.radioBox.accentColor = color.uiColor + } + + cell.set(with: molecule, delegateObject, nil) cell.updateView(size ?? collectionView.bounds.width) if molecule.selected { collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically) @@ -134,18 +141,18 @@ extension RadioBoxes: UICollectionViewDataSource { } extension RadioBoxes: UICollectionViewDelegate { - public func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { + open func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { guard let molecule = boxes?[indexPath.row] else { return false } return molecule.enabled } - public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return } cell.radioBox.selectBox() _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) } - public func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { + open func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return } cell.radioBox.deselectBox() } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift index 55c29e35..5b568910 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift @@ -9,9 +9,10 @@ import Foundation @objcMembers public class RadioBoxesModel: MoleculeModelProtocol, FormFieldProtocol { public static var identifier: String = "radioBoxes" + public var boxes: [RadioBoxModel] public var backgroundColor: Color? public var selectedAccentColor: Color? - public var boxes: [RadioBoxModel] + public var boxesColor: Color? public var fieldKey: String? public var groupName: String = FormValidator.defaultGroupName public var baseValue: AnyHashable? @@ -27,7 +28,8 @@ import Foundation private enum CodingKeys: String, CodingKey { case moleculeName case selectedAccentColor - case backgroundColor = "boxesColor" + case backgroundColor + case boxesColor case boxes case fieldKey case groupName @@ -37,6 +39,7 @@ import Foundation let typeContainer = try decoder.container(keyedBy: CodingKeys.self) selectedAccentColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + boxesColor = try typeContainer.decodeIfPresent(Color.self, forKey: .boxesColor) boxes = try typeContainer.decode([RadioBoxModel].self, forKey: .boxes) fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { From af28134d90f9990266c429757cfb6cd8dee1cbe6 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 16 Apr 2020 13:49:52 -0400 Subject: [PATCH 26/34] final clean --- MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift index ef648f06..2a6ba953 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift @@ -16,7 +16,9 @@ open class RadioBoxes: View { private let boxHeight: CGFloat = 64.0 private let itemSpacing: CGFloat = 8.0 private var numberOfColumns: CGFloat = 2.0 - private var radioBoxesModel: RadioBoxesModel! + private var radioBoxesModel: RadioBoxesModel? { + return model as? RadioBoxesModel + } private var delegateObject: MVMCoreUIDelegateObject? @@ -49,7 +51,6 @@ open class RadioBoxes: View { self.delegateObject = delegateObject guard let radioBoxesModel = model as? RadioBoxesModel else { return } - self.radioBoxesModel = radioBoxesModel boxes = radioBoxesModel.boxes FormValidator.setupValidation(for: radioBoxesModel, delegate: delegateObject?.formHolderDelegate) From 7e2e974f15b68c88a531da72c6c05ff140834bb9 Mon Sep 17 00:00:00 2001 From: Kruthika KP <> Date: Fri, 17 Apr 2020 13:06:19 +0530 Subject: [PATCH 27/34] changed implementation --- ...htVariablePriceChangeAllTextAndLinks.swift | 32 ++++++++++++++----- ...iablePriceChangeAllTextAndLinksModel.swift | 7 ---- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift index 6d179922..7355d17c 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift @@ -13,24 +13,22 @@ import Foundation //----------------------------------------------------- // MARK: - Outlets //----------------------------------------------------- - open var stack: Stack public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) public let rightLabel = Label.commonLabelB2(true) public let arrow = Arrow(frame: .zero) public let arrowAndLabel2Stack: Stack + let view = MVMCoreUICommonViewsUtility.commonView() //----------------------------------------------------- // MARK: - Initializers //----------------------------------------------------- public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { arrowAndLabel2Stack = Stack.createStack(with: [(view: arrow, model: StackItemModel(horizontalAlignment: .trailing)), - (view: rightLabel, model: StackItemModel(horizontalAlignment: .fill))], - axis: .horizontal, spacing: 6) + (view: rightLabel, model: StackItemModel(horizontalAlignment: .trailing))], + axis: .horizontal, spacing: 8) rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal) rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal) - stack = Stack.createStack(with: [(view: eyebrowHeadlineBodyLink, model: StackItemModel(percent: 70, horizontalAlignment: .leading)), - (view: arrowAndLabel2Stack, model: StackItemModel(percent: 30, horizontalAlignment: .fill, verticalAlignment: .top))], - axis: .horizontal) + rightLabel.numberOfLines = 1 super.init(style: style, reuseIdentifier: reuseIdentifier) } @@ -41,12 +39,30 @@ import Foundation //----------------------------------------------------- // MARK: - View Lifecycle //----------------------------------------------------- + override open func setupView() { super.setupView() - addMolecule(stack) arrow.pinHeightAndWidth() arrowAndLabel2Stack.restack() - stack.restack() + + view.addSubview(eyebrowHeadlineBodyLink) + view.addSubview(arrowAndLabel2Stack) + contentView.addSubview(view) + containerHelper.constrainView(view) + + //constraints + arrowAndLabel2Stack.leadingAnchor.constraint(equalTo: eyebrowHeadlineBodyLink.trailingAnchor, constant: PaddingTen).isActive = true + arrowAndLabel2Stack.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true + arrowAndLabel2Stack.topAnchor.constraint(equalTo: view.topAnchor, constant: PaddingTwo).isActive = true + + eyebrowHeadlineBodyLink.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true + eyebrowHeadlineBodyLink.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true + eyebrowHeadlineBodyLink.topAnchor.constraint(equalTo: view.topAnchor).isActive = true + } + + public override func updateView(_ size: CGFloat) { + super.updateView(size) + eyebrowHeadlineBodyLink.updateView(size) } open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinksModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinksModel.swift index c0f749e2..c048c973 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinksModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinksModel.swift @@ -22,13 +22,6 @@ public class ListRightVariablePriceChangeAllTextAndLinksModel: ListItemModel, Mo super.init() } - override public func setDefaults() { - super.setDefaults() - if let headline = eyebrowHeadlineBodyLink.headline { - headline.hero = 0 - } - } - private enum CodingKeys: String, CodingKey { case moleculeName case eyebrowHeadlineBodyLink From 135bf4c073df588a41751478f2b58451edc2a5a6 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Fri, 17 Apr 2020 16:30:49 +0530 Subject: [PATCH 28/34] Code cleanup --- .../Atomic/Atoms/Selectors/RadioSwatchItem.swift | 12 ++++-------- .../RadioSwatchItemCollectionViewCell.swift | 2 +- .../Atomic/Atoms/Selectors/RadioSwatches.swift | 13 +++++++------ .../Atomic/Atoms/Selectors/RadioSwatchesModel.swift | 1 - 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift index 9117aee8..a6e6b802 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift @@ -13,7 +13,7 @@ open class RadioSwatchItem: Control { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - public var bottomText = Label.createLabelRegularMicro(true) + public let bottomText = Label.createLabelRegularMicro(true) public var isOutOfStock = false public var fillColor: Color = Color(uiColor: .mvmBlue) @@ -35,19 +35,16 @@ open class RadioSwatchItem: Control { layer.setNeedsDisplay() } - public override func setupView() { + open override func setupView() { super.setupView() addSubview(bottomText) bottomText.textAlignment = .center - bottomText.topAnchor.constraint(equalTo: topAnchor, constant: 38).isActive = true - bottomText.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true - bottomText.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true - bottomAnchor.constraint(equalTo: bottomText.bottomAnchor).isActive = true + NSLayoutConstraint.constraintPinSubview(bottomText, pinTop: true, topConstant: 38, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: 0, pinRight: true, rightConstant: 0) addTarget(self, action: #selector(selectSwatch), for: .touchUpInside) } - public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) guard let model = model as? RadioSwatchItemModel else { return } fillColor = model.color @@ -60,7 +57,6 @@ open class RadioSwatchItem: Control { //------------------------------------------------------ // MARK: - State Handling //------------------------------------------------------ - open override func draw(_ layer: CALayer, in ctx: CGContext) { //Draw the swatch circleLayer?.removeFromSuperlayer() diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift index 3d3100a8..a820a680 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift @@ -8,7 +8,7 @@ import Foundation open class RadioSwatchItemCollectionViewCell: CollectionViewCell { - let radioSwatch = RadioSwatchItem() + public let radioSwatch = RadioSwatchItem() open override func setupView() { super.setupView() diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift index 2811da69..f13dd331 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift @@ -13,9 +13,9 @@ open class RadioSwatches: View { // MARK: - Properties //-------------------------------------------------- public var collectionView: CollectionView! - var swatches: [RadioSwatchItemModel]? + public var swatches: [RadioSwatchItemModel]? private var size: CGFloat? - private var delegateObject: MVMCoreUIDelegateObject? + private var delegateObject: MVMCoreUIDelegateObject? //------------------------------------------------------ // MARK: - Constraints @@ -50,7 +50,7 @@ open class RadioSwatches: View { collectionView.updateView(size) } - public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) self.delegateObject = delegateObject @@ -65,6 +65,7 @@ open class RadioSwatches: View { //------------------------------------------------------ // MARK: - Methods //------------------------------------------------------ + /// Registers the cells with the collection view open func registerCells() { collectionView.register(RadioSwatchItemCollectionViewCell.self, forCellWithReuseIdentifier: "RadioSwatchItemCollectionViewCell") } @@ -130,17 +131,17 @@ extension RadioSwatches: UICollectionViewDataSource { } extension RadioSwatches: UICollectionViewDelegate { - public func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { + open func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { guard let molecule = swatches?[indexPath.row] else {return true } return molecule.enabled ?? true } - public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchItemCollectionViewCell else { return } cell.radioSwatch.selectSwatch() _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) } - public func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { + open func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchItemCollectionViewCell else { return } cell.radioSwatch.deselectSwatch() } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift index 965b72f6..d422d0db 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift @@ -61,7 +61,6 @@ import Foundation public var selected: Bool? = false public var enabled: Bool? = true public var strikethrough: Bool? = false - public var fieldKey: String? public var fieldValue: String? private enum CodingKeys: String, CodingKey { From 7471d2adf68375bf6a97cd948d5e20ff4f196342 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 17 Apr 2020 19:05:01 -0400 Subject: [PATCH 29/34] Separate radio swatch model file remove item from radio swatch name add in reset function to be consistent. Fix selected color issues with outer circle Center line Move height calculations to be dynamic minor encoding updates --- MVMCoreUI.xcodeproj/project.pbxproj | 20 +++--- ...adioSwatchItem.swift => RadioSwatch.swift} | 46 +++++++------ ...ft => RadioSwatchCollectionViewCell.swift} | 8 +-- .../Atoms/Selectors/RadioSwatchModel.swift | 64 ++++++++++++++++++ .../Atoms/Selectors/RadioSwatches.swift | 36 +++++----- .../Atoms/Selectors/RadioSwatchesModel.swift | 67 ++----------------- 6 files changed, 130 insertions(+), 111 deletions(-) rename MVMCoreUI/Atomic/Atoms/Selectors/{RadioSwatchItem.swift => RadioSwatch.swift} (77%) rename MVMCoreUI/Atomic/Atoms/Selectors/{RadioSwatchItemCollectionViewCell.swift => RadioSwatchCollectionViewCell.swift} (71%) create mode 100644 MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 077b0ca2..befe232c 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -190,11 +190,11 @@ AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA1EC59824373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift */; }; AA56A20F243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA56A20E243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift */; }; AA56A211243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA56A210243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift */; }; - AA85236C244435A20059CC1E /* RadioSwatchItemCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA85236B244435A20059CC1E /* RadioSwatchItemCollectionViewCell.swift */; }; + AA85236C244435A20059CC1E /* RadioSwatchCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */; }; AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */; }; AAA74A192410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */; }; AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; }; - AAB9C10A243496DD00151545 /* RadioSwatchItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatchItem.swift */; }; + AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatch.swift */; }; AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; }; BB2C968F24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */; }; BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */; }; @@ -226,6 +226,7 @@ C7F8012323E846C300396FBD /* ListRVWheelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7F8012223E846C300396FBD /* ListRVWheelModel.swift */; }; D202AFE4242A5F5E00E5BEDF /* NSTextAlignment+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D202AFE3242A5F5E00E5BEDF /* NSTextAlignment+Extension.swift */; }; D202AFE6242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */; }; + D2092349244A51D40044AD09 /* RadioSwatchModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2092348244A51D40044AD09 /* RadioSwatchModel.swift */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; D20FB165241A5D75004AFC3A /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */; }; D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; }; @@ -620,11 +621,11 @@ AA1EC59824373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListThreeColumnSpeedTestDivider.swift; sourceTree = ""; }; AA56A20E243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnSubsectionDividerModel.swift; sourceTree = ""; }; AA56A210243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnSubsectionDivider.swift; sourceTree = ""; }; - AA85236B244435A20059CC1E /* RadioSwatchItemCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchItemCollectionViewCell.swift; sourceTree = ""; }; + AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchCollectionViewCell.swift; sourceTree = ""; }; AAA74A162410C04600080241 /* HeadersH2NoButtonsBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyText.swift; sourceTree = ""; }; AAA74A182410C05800080241 /* HeadersH2NoButtonsBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2NoButtonsBodyTextModel.swift; sourceTree = ""; }; AAB9C10724346F4B00151545 /* RadioSwatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatches.swift; sourceTree = ""; }; - AAB9C109243496DD00151545 /* RadioSwatchItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchItem.swift; sourceTree = ""; }; + AAB9C109243496DD00151545 /* RadioSwatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatch.swift; sourceTree = ""; }; AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.swift; sourceTree = ""; }; BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinksModel.swift; sourceTree = ""; }; BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinks.swift; sourceTree = ""; }; @@ -656,6 +657,7 @@ C7F8012223E846C300396FBD /* ListRVWheelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRVWheelModel.swift; sourceTree = ""; }; D202AFE3242A5F5E00E5BEDF /* NSTextAlignment+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSTextAlignment+Extension.swift"; sourceTree = ""; }; D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UICollectionViewScrollPosition+Extension.swift"; sourceTree = ""; }; + D2092348244A51D40044AD09 /* RadioSwatchModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchModel.swift; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = ""; }; D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; @@ -1439,8 +1441,9 @@ 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */, AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */, AAB9C10724346F4B00151545 /* RadioSwatches.swift */, - AAB9C109243496DD00151545 /* RadioSwatchItem.swift */, - AA85236B244435A20059CC1E /* RadioSwatchItemCollectionViewCell.swift */, + D2092348244A51D40044AD09 /* RadioSwatchModel.swift */, + AAB9C109243496DD00151545 /* RadioSwatch.swift */, + AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */, ); path = Selectors; sourceTree = ""; @@ -2114,7 +2117,7 @@ 012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */, BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */, D21B7F77243BB70700051ABF /* MoleculeCollectionItemModel.swift in Sources */, - AAB9C10A243496DD00151545 /* RadioSwatchItem.swift in Sources */, + AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */, D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */, 011D9602240DA20A000E3791 /* FormRuleWatcherFieldProtocol.swift in Sources */, D264FAA1243CF66B00D98315 /* ContainerCollectionReusableView.swift in Sources */, @@ -2219,6 +2222,7 @@ D260105D23D0BCD400764D80 /* Stack.swift in Sources */, 0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */, BB54C5212434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift in Sources */, + D2092349244A51D40044AD09 /* RadioSwatchModel.swift in Sources */, 8DD1E370243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift in Sources */, D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */, 01EB368F23609801006832FA /* LabelModel.swift in Sources */, @@ -2333,7 +2337,7 @@ 0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */, AA56A211243C5EFC00303286 /* ListTwoColumnSubsectionDivider.swift in Sources */, D264FA8C243BCD8E00D98315 /* CollectionTemplateModel.swift in Sources */, - AA85236C244435A20059CC1E /* RadioSwatchItemCollectionViewCell.swift in Sources */, + AA85236C244435A20059CC1E /* RadioSwatchCollectionViewCell.swift in Sources */, 52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */, D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */, 0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatch.swift similarity index 77% rename from MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatch.swift index a6e6b802..35294457 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItem.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatch.swift @@ -1,5 +1,5 @@ // -// RadioSwatchItem.swift +// RadioSwatch.swift // MVMCoreUI // // Created by Lekshmi S on 01/04/20. @@ -9,21 +9,19 @@ import Foundation import UIKit -open class RadioSwatchItem: Control { +open class RadioSwatch: Control { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- public let bottomText = Label.createLabelRegularMicro(true) - public var isOutOfStock = false - public var fillColor: Color = Color(uiColor: .mvmBlue) private var circleLayer: CAShapeLayer? private var selectedLayer: CALayer? private var strikeLayer: CALayer? private var maskLayer: CALayer? - public var radioSwatchModel: RadioSwatchItemModel? { - return model as? RadioSwatchItemModel + public var radioSwatchModel: RadioSwatchModel? { + return model as? RadioSwatchModel } //-------------------------------------------------- @@ -40,18 +38,23 @@ open class RadioSwatchItem: Control { addSubview(bottomText) bottomText.textAlignment = .center - NSLayoutConstraint.constraintPinSubview(bottomText, pinTop: true, topConstant: 38, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: 0, pinRight: true, rightConstant: 0) + NSLayoutConstraint.constraintPinSubview(bottomText, pinTop: true, topConstant: 38, pinBottom: true, bottomConstant: 0, pinLeft: true, leftConstant: 0, pinRight: true, rightConstant: 0) addTarget(self, action: #selector(selectSwatch), for: .touchUpInside) } open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) - guard let model = model as? RadioSwatchItemModel else { return } - fillColor = model.color - isSelected = model.selected ?? false - isEnabled = model.enabled ?? true + guard let model = model as? RadioSwatchModel else { return } + isSelected = model.selected + isEnabled = model.enabled bottomText.text = model.text - isOutOfStock = model.strikethrough ?? false + } + + public override func reset() { + super.reset() + isSelected = false + isEnabled = true + bottomText.text = nil } //------------------------------------------------------ @@ -60,14 +63,14 @@ open class RadioSwatchItem: Control { open override func draw(_ layer: CALayer, in ctx: CGContext) { //Draw the swatch circleLayer?.removeFromSuperlayer() - let circle = getCircle(color: .mvmBlack, thickness: 1) + let circle = getCircle(color: isSelected ? .mvmBlack : .mvmCoolGray6, thickness: 1) layer.addSublayer(circle) circleLayer = circle //Draw the strikethrough strikeLayer?.removeFromSuperlayer() - if isOutOfStock { - let line = getStrikeThrough(color: .mvmBlack, thickness: 1) + if radioSwatchModel?.strikethrough ?? false { + let line = getStrikeThrough(color: isSelected ? .mvmBlack : .mvmCoolGray6, thickness: 1) layer.addSublayer(line) strikeLayer = line } @@ -75,12 +78,11 @@ open class RadioSwatchItem: Control { //Draw the selected layer selectedLayer?.removeFromSuperlayer() if isSelected { - let outerCircle = getSelectedLayer(color: .mvmBlack, thickness: 1) + let outerCircle = getSelectedLayer(color: isSelected ? .mvmBlack : .mvmCoolGray6, thickness: 1) layer.addSublayer(outerCircle) selectedLayer = outerCircle bottomText.isHidden = false } else { - circleLayer?.path = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)).cgPath bottomText.isHidden = true } @@ -115,10 +117,10 @@ open class RadioSwatchItem: Control { func getCircle(color: UIColor, thickness: CGFloat) -> CAShapeLayer { let circle = CAShapeLayer() circle.name = "innercircle" - circle.fillColor = fillColor.cgColor + circle.fillColor = radioSwatchModel?.color.cgColor ?? UIColor.blue.cgColor circle.opacity = 1.0 circle.lineWidth = thickness - circle.strokeColor = isSelected ? color.cgColor : UIColor.mvmCoolGray6.cgColor + circle.strokeColor = color.cgColor let circlePath = UIBezierPath(ovalIn: CGRect(x: 12, y: 1, width: 30, height: 30)) circle.path = circlePath.cgPath @@ -131,11 +133,11 @@ open class RadioSwatchItem: Control { strikeThrough.fillColor = nil strikeThrough.opacity = 1.0 strikeThrough.lineWidth = thickness - strikeThrough.strokeColor = isSelected ? color.cgColor : UIColor.mvmCoolGray6.cgColor + strikeThrough.strokeColor = color.cgColor let linePath = UIBezierPath() - linePath.move(to: CGPoint(x: 12, y: 30)) - linePath.addLine(to: CGPoint(x: 42, y: 0)) + linePath.move(to: CGPoint(x: 12, y: 31)) + linePath.addLine(to: CGPoint(x: 42, y: 1)) strikeThrough.path = linePath.cgPath return strikeThrough } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchCollectionViewCell.swift similarity index 71% rename from MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchCollectionViewCell.swift index a820a680..8412dab2 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchItemCollectionViewCell.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchCollectionViewCell.swift @@ -1,5 +1,5 @@ // -// RadioSwatchItemCollectionViewCell.swift +// RadioSwatchCollectionViewCell.swift // MVMCoreUI // // Created by Lekshmi S on 13/04/20. @@ -7,8 +7,8 @@ // import Foundation -open class RadioSwatchItemCollectionViewCell: CollectionViewCell { - public let radioSwatch = RadioSwatchItem() +open class RadioSwatchCollectionViewCell: CollectionViewCell { + public let radioSwatch = RadioSwatch() open override func setupView() { super.setupView() @@ -17,7 +17,7 @@ open class RadioSwatchItemCollectionViewCell: CollectionViewCell { } open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - guard let model = model as? RadioSwatchItemModel else { return } + guard let model = model as? RadioSwatchModel else { return } radioSwatch.set(with: model, delegateObject, additionalData) } } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift new file mode 100644 index 00000000..3aadd467 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift @@ -0,0 +1,64 @@ +// +// RadioSwatchModel.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 4/17/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers public class RadioSwatchModel: MoleculeModelProtocol { + public static var identifier: String = "radioSwatch" + public var backgroundColor: Color? + public var color: Color = Color(uiColor: .mvmBlue) + public var text: String? + public var selected: Bool = false + public var enabled: Bool = true + public var strikethrough: Bool = false + public var fieldValue: String? + + private enum CodingKeys: String, CodingKey { + case moleculeName + case backgroundColor + case color + case text + case selected + case enabled + case strikethrough + case fieldValue + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) { + self.color = color + } + text = try typeContainer.decodeIfPresent(String.self, forKey: .text) + if let selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) { + self.selected = selected + } + if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { + self.enabled = enabled + } + if let strikethrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) { + self.strikethrough = strikethrough + } + fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue) + } + + 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.encode(color, forKey: .color) + try container.encodeIfPresent(text, forKey: .text) + try container.encode(selected, forKey: .selected) + try container.encode(enabled, forKey: .enabled) + try container.encode(strikethrough, forKey: .strikethrough) + try container.encodeIfPresent(fieldValue, forKey: .fieldValue) + } +} + + diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift index f13dd331..8a6b8faf 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatches.swift @@ -13,7 +13,7 @@ open class RadioSwatches: View { // MARK: - Properties //-------------------------------------------------- public var collectionView: CollectionView! - public var swatches: [RadioSwatchItemModel]? + public var swatches: [RadioSwatchModel]? private var size: CGFloat? private var delegateObject: MVMCoreUIDelegateObject? @@ -30,6 +30,7 @@ open class RadioSwatches: View { open override func layoutSubviews() { super.layoutSubviews() // Accounts for any collection size changes + setHeight() DispatchQueue.main.async { self.collectionView.collectionViewLayout.invalidateLayout() } @@ -57,24 +58,18 @@ open class RadioSwatches: View { guard let radioSwatchesModel = model as? RadioSwatchesModel else { return } swatches = radioSwatchesModel.swatches FormValidator.setupValidation(for: radioSwatchesModel, delegate: delegateObject?.formHolderDelegate) - registerCells() - setHeight() collectionView.reloadData() } //------------------------------------------------------ // MARK: - Methods //------------------------------------------------------ - /// Registers the cells with the collection view - open func registerCells() { - collectionView.register(RadioSwatchItemCollectionViewCell.self, forCellWithReuseIdentifier: "RadioSwatchItemCollectionViewCell") - } - /// Creates the collection view. open func createCollectionView() -> CollectionView { let collection = CollectionView(frame: .zero, collectionViewLayout: createCollectionViewLayout()) collection.dataSource = self collection.delegate = self + collection.register(RadioSwatchCollectionViewCell.self, forCellWithReuseIdentifier: "RadioSwatchCollectionViewCell") return collection } @@ -93,10 +88,17 @@ open class RadioSwatches: View { return } // Calculate the height - let collectionViewWidth = UIScreen.main.bounds.width - (2 * MFStyler.defaultHorizontalPaddingForApplicationWidth()) - let swatchesInRow = floor(CGFloat(collectionViewWidth/(cellSize + itemSpacing))) + let swatchesInRow = floor(CGFloat(collectionView.bounds.width/(cellSize + itemSpacing))) let numberOfRows = ceil(CGFloat(swatches.count)/swatchesInRow) let height = (numberOfRows * cellSize) + (itemSpacing * (numberOfRows-1)) + + if let oldHeight = collectionViewHeight?.constant, + height != oldHeight { + // Notify delegate of height change, called async to avoid various race conditions caused while happening while laying out initially. + DispatchQueue.main.async { + self.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self) + } + } collectionViewHeight?.constant = CGFloat(height) } } @@ -116,13 +118,14 @@ extension RadioSwatches: UICollectionViewDataSource { } open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - guard let molecule = swatches?[indexPath.row], let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioSwatchItemCollectionViewCell", for: indexPath) as? RadioSwatchItemCollectionViewCell else { + guard let molecule = swatches?[indexPath.row], let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioSwatchCollectionViewCell", for: indexPath) as? RadioSwatchCollectionViewCell else { fatalError() } + cell.reset() cell.radioSwatch.isUserInteractionEnabled = false cell.set(with: molecule, delegateObject, nil) cell.updateView(size ?? collectionView.bounds.width) - if molecule.selected ?? false { + if molecule.selected { collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically) } cell.layoutIfNeeded() @@ -132,17 +135,18 @@ extension RadioSwatches: UICollectionViewDataSource { extension RadioSwatches: UICollectionViewDelegate { open func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { - guard let molecule = swatches?[indexPath.row] else {return true } - return molecule.enabled ?? true + guard let molecule = swatches?[indexPath.row] else { return false } + return molecule.enabled } open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchItemCollectionViewCell else { return } + guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchCollectionViewCell else { return } cell.radioSwatch.selectSwatch() _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) } + open func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { - guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchItemCollectionViewCell else { return } + guard let cell = collectionView.cellForItem(at: indexPath) as? RadioSwatchCollectionViewCell else { return } cell.radioSwatch.deselectSwatch() } } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift index d422d0db..db8e5d5d 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift @@ -9,9 +9,9 @@ import Foundation @objcMembers public class RadioSwatchesModel: MoleculeModelProtocol, FormFieldProtocol { - public var backgroundColor: Color? public static var identifier: String = "radioSwatches" - public var swatches: [RadioSwatchItemModel] + public var backgroundColor: Color? + public var swatches: [RadioSwatchModel] public var fieldKey: String? public var groupName: String = FormValidator.defaultGroupName public var baseValue: AnyHashable? @@ -19,7 +19,7 @@ import Foundation /// Returns the fieldValue of the selected swatch, otherwise the text of selected swatch. public func formFieldValue() -> AnyHashable? { let selectedSwatch = swatches.first { (swatch) -> Bool in - return (swatch.selected ?? false) + return swatch.selected } return selectedSwatch?.fieldValue ?? selectedSwatch?.text } @@ -34,8 +34,8 @@ import Foundation required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - self.backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - self.swatches = try typeContainer.decode([RadioSwatchItemModel].self, forKey: .swatches) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + swatches = try typeContainer.decode([RadioSwatchModel].self, forKey: .swatches) fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { self.groupName = groupName @@ -49,61 +49,6 @@ import Foundation try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(swatches, forKey: .swatches) try container.encodeIfPresent(fieldKey, forKey: .fieldKey) - try container.encodeIfPresent(groupName, forKey: .groupName) + try container.encode(groupName, forKey: .groupName) } } - -@objcMembers public class RadioSwatchItemModel: MoleculeModelProtocol { - public var backgroundColor: Color? - public static var identifier: String = "radioSwatchItem" - public var color: Color = Color(uiColor: .mvmBlue) - public var text: String? - public var selected: Bool? = false - public var enabled: Bool? = true - public var strikethrough: Bool? = false - public var fieldValue: String? - - private enum CodingKeys: String, CodingKey { - case moleculeName - case backgroundColor - case color - case text - case selected - case enabled - case strikethrough - case fieldValue - } - - required public init(from decoder: Decoder) throws { - let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - color = try typeContainer.decode(Color.self, forKey: .color) - if let text = try typeContainer.decodeIfPresent(String.self, forKey: .text) { - self.text = text - } - if let selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) { - self.selected = selected - } - if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { - self.enabled = enabled - } - if let strikethrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) { - self.strikethrough = strikethrough - } - fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue) - } - - 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.encode(color, forKey: .color) - try container.encodeIfPresent(text, forKey: .text) - try container.encodeIfPresent(selected, forKey: .selected) - try container.encodeIfPresent(enabled, forKey: .enabled) - try container.encodeIfPresent(strikethrough, forKey: .strikethrough) - try container.encodeIfPresent(fieldValue, forKey: .fieldValue) - } -} - - From c89929648fceea3dc4de7f233c5d39ffc9be5d94 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Sat, 18 Apr 2020 17:45:14 -0400 Subject: [PATCH 30/34] fix centering logic --- ...htVariablePriceChangeAllTextAndLinks.swift | 31 ++++++++++++------- MVMCoreUI/BaseClasses/TableViewCell.swift | 2 +- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift index 7355d17c..182e2cee 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift @@ -18,13 +18,14 @@ import Foundation public let arrow = Arrow(frame: .zero) public let arrowAndLabel2Stack: Stack let view = MVMCoreUICommonViewsUtility.commonView() + public var alignmentConstraint: NSLayoutConstraint? //----------------------------------------------------- // MARK: - Initializers //----------------------------------------------------- public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - arrowAndLabel2Stack = Stack.createStack(with: [(view: arrow, model: StackItemModel(horizontalAlignment: .trailing)), - (view: rightLabel, model: StackItemModel(horizontalAlignment: .trailing))], + arrowAndLabel2Stack = Stack.createStack(with: [(view: arrow, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .center)), + (view: rightLabel, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .center))], axis: .horizontal, spacing: 8) rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal) rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal) @@ -40,29 +41,35 @@ import Foundation // MARK: - View Lifecycle //----------------------------------------------------- + public override func alignAccessoryToHero() { + super.alignAccessoryToHero() + + // Aligns the center of the right side to the headline. + if let heroCenter = heroAccessoryCenter { + let convertedPoint = view.convert(heroCenter, from: self) + alignmentConstraint?.constant = convertedPoint.y - view.bounds.midY + } + } + override open func setupView() { super.setupView() arrow.pinHeightAndWidth() arrowAndLabel2Stack.restack() - view.addSubview(eyebrowHeadlineBodyLink) view.addSubview(arrowAndLabel2Stack) contentView.addSubview(view) containerHelper.constrainView(view) - //constraints - arrowAndLabel2Stack.leadingAnchor.constraint(equalTo: eyebrowHeadlineBodyLink.trailingAnchor, constant: PaddingTen).isActive = true - arrowAndLabel2Stack.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true - arrowAndLabel2Stack.topAnchor.constraint(equalTo: view.topAnchor, constant: PaddingTwo).isActive = true - - eyebrowHeadlineBodyLink.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true - eyebrowHeadlineBodyLink.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true - eyebrowHeadlineBodyLink.topAnchor.constraint(equalTo: view.topAnchor).isActive = true + NSLayoutConstraint.pinViews(leftView: eyebrowHeadlineBodyLink, rightView: arrowAndLabel2Stack, alignTop: false) + alignmentConstraint = view.constraintsAffectingLayout(for: .vertical).first { (layout) -> Bool in + return layout.firstAnchor == arrowAndLabel2Stack.centerYAnchor && layout.firstAttribute == .centerY + } } public override func updateView(_ size: CGFloat) { super.updateView(size) eyebrowHeadlineBodyLink.updateView(size) + arrowAndLabel2Stack.updateView(size) } open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { @@ -79,6 +86,8 @@ import Foundation open override func reset() { super.reset() + eyebrowHeadlineBodyLink.reset() + arrowAndLabel2Stack.reset() rightLabel.styleB2(true) } } diff --git a/MVMCoreUI/BaseClasses/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift index dc4d270a..8170e402 100644 --- a/MVMCoreUI/BaseClasses/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -26,7 +26,7 @@ import UIKit /// For subclasses that want to use a custom accessory view. open var customAccessoryView = false - private var heroAccessoryCenter: CGPoint? + public var heroAccessoryCenter: CGPoint? private var initialSetupPerformed = false From 4d7740854daef8f8072f23df00dd5c6ba380d269 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Sat, 18 Apr 2020 18:08:13 -0400 Subject: [PATCH 31/34] Simpler stack logic --- ...htVariablePriceChangeAllTextAndLinks.swift | 59 ++++++++----------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift index 182e2cee..f13d9f4c 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift @@ -14,22 +14,24 @@ import Foundation // MARK: - Outlets //----------------------------------------------------- public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) - public let rightLabel = Label.commonLabelB2(true) public let arrow = Arrow(frame: .zero) - public let arrowAndLabel2Stack: Stack - let view = MVMCoreUICommonViewsUtility.commonView() - public var alignmentConstraint: NSLayoutConstraint? + public let rightLabel = Label.commonLabelB2(true) + private let stack: Stack + private let arrowStackItem: StackItem + private let rightLabelStackItem: StackItem //----------------------------------------------------- // MARK: - Initializers //----------------------------------------------------- public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - arrowAndLabel2Stack = Stack.createStack(with: [(view: arrow, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .center)), - (view: rightLabel, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .center))], - axis: .horizontal, spacing: 8) - rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal) - rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal) - rightLabel.numberOfLines = 1 + let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .leading), + StackItemModel(horizontalAlignment: .fill), + StackItemModel(spacing: 8, horizontalAlignment: .fill)], + axis: .horizontal) + arrowStackItem = StackItem(andContain: arrow) + rightLabelStackItem = StackItem(andContain: rightLabel) + let stackItems = [StackItem(andContain: eyebrowHeadlineBodyLink), arrowStackItem, rightLabelStackItem] + stack = Stack(with: stackModel, stackItems: stackItems) super.init(style: style, reuseIdentifier: reuseIdentifier) } @@ -44,32 +46,24 @@ import Foundation public override func alignAccessoryToHero() { super.alignAccessoryToHero() - // Aligns the center of the right side to the headline. + // Aligns the center of the right side items to the headline. if let heroCenter = heroAccessoryCenter { - let convertedPoint = view.convert(heroCenter, from: self) - alignmentConstraint?.constant = convertedPoint.y - view.bounds.midY + let convertedPoint = stack.convert(heroCenter, from: self) + arrowStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - stack.bounds.midY + rightLabelStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - stack.bounds.midY } } override open func setupView() { super.setupView() - arrow.pinHeightAndWidth() - arrowAndLabel2Stack.restack() - view.addSubview(eyebrowHeadlineBodyLink) - view.addSubview(arrowAndLabel2Stack) - contentView.addSubview(view) - containerHelper.constrainView(view) + rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal) + rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal) + rightLabel.numberOfLines = 1 - NSLayoutConstraint.pinViews(leftView: eyebrowHeadlineBodyLink, rightView: arrowAndLabel2Stack, alignTop: false) - alignmentConstraint = view.constraintsAffectingLayout(for: .vertical).first { (layout) -> Bool in - return layout.firstAnchor == arrowAndLabel2Stack.centerYAnchor && layout.firstAttribute == .centerY - } - } - - public override func updateView(_ size: CGFloat) { - super.updateView(size) - eyebrowHeadlineBodyLink.updateView(size) - arrowAndLabel2Stack.updateView(size) + arrow.pinHeightAndWidth() + + addMolecule(stack) + stack.restack() } open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { @@ -83,12 +77,5 @@ import Foundation open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 121 } - - open override func reset() { - super.reset() - eyebrowHeadlineBodyLink.reset() - arrowAndLabel2Stack.reset() - rightLabel.styleB2(true) - } } From b061952e02a8a20a0a96fdd23327d4649c0df1be Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Sat, 18 Apr 2020 18:10:51 -0400 Subject: [PATCH 32/34] organize --- MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 0457a23d..3fb78647 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -142,6 +142,7 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTotalData.self, viewModelClass: ListRightVariableTotalDataModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTextLinkAllTextAndLinks.self, viewModelClass: ListRightVariableTextLinkAllTextAndLinksModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableButtonAllTextAndLinks.self, viewModelClass: ListRightVariableButtonAllTextAndLinksModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeAllTextAndLinks.self, viewModelClass: ListRightVariablePriceChangeAllTextAndLinksModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextAllTextAndLinks.self, viewModelClass: ListOneColumnFullWidthTextAllTextAndLinksModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextBodyText.self, viewModelClass: ListOneColumnFullWidthTextBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnCompareChanges.self, viewModelClass: ListTwoColumnCompareChangesModel.self) @@ -149,7 +150,6 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnPriceDescription.self, viewModelClass: ListTwoColumnPriceDescriptionModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnInternationalData.self, viewModelClass: ListThreeColumnInternationalDataModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self) - MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeAllTextAndLinks.self, viewModelClass: ListRightVariablePriceChangeAllTextAndLinksModel.self) // Designed Section Dividers MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self) From 9cff0f15f7bacca7951f0bee3d22f7336cde8b04 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Sat, 18 Apr 2020 19:09:19 -0400 Subject: [PATCH 33/34] hero fixes headlineBody update instead of eyebrowheadlinebody --- MVMCoreUI.xcodeproj/project.pbxproj | 4 +-- ...htVariablePriceChangeAllTextAndLinks.swift | 13 ++++----- ...iablePriceChangeAllTextAndLinksModel.swift | 1 - ...ListRightVariablePriceChangeBodyText.swift | 27 ++++++++++++------- ...ightVariablePriceChangeBodyTextModel.swift | 20 +++++++++----- MVMCoreUI/BaseClasses/TableViewCell.swift | 12 +++++---- 6 files changed, 47 insertions(+), 30 deletions(-) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 227863dc..00550bbe 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -1103,8 +1103,6 @@ AA4FC2A323F4F69600E251DB /* RightVariable */ = { isa = PBXGroup; children = ( - BB55B51E244482D2002001AD /* ListRightVariablePriceChangeBodyTextModel.swift */, - BB55B51C244482C0002001AD /* ListRightVariablePriceChangeBodyText.swift */, BB54C51F2434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift */, BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */, BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */, @@ -1113,6 +1111,8 @@ AA11A41E23F15D3100D7962F /* ListRightVariablePayments.swift */, 8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */, 8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */, + BB55B51E244482D2002001AD /* ListRightVariablePriceChangeBodyTextModel.swift */, + BB55B51C244482C0002001AD /* ListRightVariablePriceChangeBodyText.swift */, 8D8067D02444472F00203BE8 /* ListRightVariablePriceChangeAllTextAndLinksModel.swift */, 8D8067D22444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift */, C7F8012223E846C300396FBD /* ListRVWheelModel.swift */, diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift index f13d9f4c..7a74de6e 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinks.swift @@ -8,7 +8,7 @@ import Foundation -@objcMembers public class ListRightVariablePriceChangeAllTextAndLinks: TableViewCell { +@objcMembers open class ListRightVariablePriceChangeAllTextAndLinks: TableViewCell { //----------------------------------------------------- // MARK: - Outlets @@ -26,7 +26,7 @@ import Foundation public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .leading), StackItemModel(horizontalAlignment: .fill), - StackItemModel(spacing: 8, horizontalAlignment: .fill)], + StackItemModel(spacing: 6, horizontalAlignment: .fill)], axis: .horizontal) arrowStackItem = StackItem(andContain: arrow) rightLabelStackItem = StackItem(andContain: rightLabel) @@ -43,18 +43,19 @@ import Foundation // MARK: - View Lifecycle //----------------------------------------------------- - public override func alignAccessoryToHero() { - super.alignAccessoryToHero() + open override func alignAccessoryToHero() -> CGPoint? { + let heroCenter = super.alignAccessoryToHero() // Aligns the center of the right side items to the headline. - if let heroCenter = heroAccessoryCenter { + if let heroCenter = heroCenter { let convertedPoint = stack.convert(heroCenter, from: self) arrowStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - stack.bounds.midY rightLabelStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - stack.bounds.midY } + return heroCenter } - override open func setupView() { + open override func setupView() { super.setupView() rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal) rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinksModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinksModel.swift index c048c973..ae4be269 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinksModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeAllTextAndLinksModel.swift @@ -9,7 +9,6 @@ import Foundation public class ListRightVariablePriceChangeAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol { - public static var identifier: String = "listRVArwAll" public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel public var rightLabel: LabelModel diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift index c62a7eaf..2b87294a 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyText.swift @@ -12,19 +12,20 @@ import Foundation //----------------------------------------------------- // MARK: - Outlets //----------------------------------------------------- - public var stack: Stack - public let headlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) - public let rightLabel = Label.commonLabelB2(true) + private let stack: Stack + public let headlineBody = HeadlineBody(frame: .zero) public let arrow = Arrow(frame: .zero) + public let rightLabel = Label.commonLabelB2(true) let arrowAndRightLabelStack: Stack + // MARK: - Initializers public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { arrowAndRightLabelStack = Stack.createStack(with: [(view: arrow, model: StackItemModel(horizontalAlignment: .fill)), - (view: rightLabel, model: StackItemModel(horizontalAlignment: .leading))], + (view: rightLabel, model: StackItemModel(horizontalAlignment: .fill))], axis: .horizontal, spacing: 6) - stack = Stack.createStack(with: [(view: headlineBodyLink, model: StackItemModel(percent:70,horizontalAlignment: .leading)), - (view: arrowAndRightLabelStack, model: StackItemModel(percent:30,horizontalAlignment: .trailing,verticalAlignment: .top))], + stack = Stack.createStack(with: [(view: headlineBody, model: StackItemModel(horizontalAlignment: .leading)), + (view: arrowAndRightLabelStack, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .leading))], axis: .horizontal) super.init(style: style, reuseIdentifier: reuseIdentifier) } @@ -36,8 +37,14 @@ import Foundation //----------------------------------------------------- // MARK: - View Lifecycle //----------------------------------------------------- - override open func setupView() { + open override func setupView() { super.setupView() + headlineBody.styleListItem() + + rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal) + rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal) + rightLabel.numberOfLines = 1 + arrow.pinHeightAndWidth() addMolecule(stack) stack.restack() @@ -47,17 +54,17 @@ import Foundation open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.set(with: model, delegateObject, additionalData) guard let model = model as? ListRightVariablePriceChangeBodyTextModel else { return } - headlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + headlineBody.set(with: model.headlineBody, delegateObject, additionalData) rightLabel.set(with: model.rightLabel, delegateObject, additionalData) arrow.set(with: model.arrow, delegateObject, additionalData) } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - return 120 + return 80 } open override func reset() { super.reset() - rightLabel.styleB2(true) + headlineBody.styleListItem() } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyTextModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyTextModel.swift index e2d90eb7..7bf118df 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyTextModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariablePriceChangeBodyTextModel.swift @@ -9,27 +9,35 @@ import Foundation public class ListRightVariablePriceChangeBodyTextModel: ListItemModel, MoleculeModelProtocol { public static var identifier: String = "listRVArwBdy" - public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel + public var headlineBody: HeadlineBodyModel public var rightLabel: LabelModel public var arrow: ArrowModel - public init(eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel,rightLabel: LabelModel,arrow: ArrowModel) { - self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink + public init(headlineBody: HeadlineBodyModel,rightLabel: LabelModel,arrow: ArrowModel) { + self.headlineBody = headlineBody self.rightLabel = rightLabel self.arrow = arrow super.init() } + /// Defaults to set + public override func setDefaults() { + super.setDefaults() + if let headline = headlineBody.headline { + headline.hero = 0 + } + } + private enum CodingKeys: String, CodingKey { case moleculeName - case eyebrowHeadlineBodyLink + case headlineBody case rightLabel case arrow } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink) + headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody) rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel) arrow = try typeContainer.decode(ArrowModel.self, forKey: .arrow) try super.init(from: decoder) @@ -39,7 +47,7 @@ public class ListRightVariablePriceChangeBodyTextModel: ListItemModel, MoleculeM try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) - try container.encode(eyebrowHeadlineBodyLink, forKey: .eyebrowHeadlineBodyLink) + try container.encode(headlineBody, forKey: .headlineBody) try container.encode(rightLabel, forKey: .rightLabel) try container.encode(arrow, forKey: .arrow) } diff --git a/MVMCoreUI/BaseClasses/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift index 8170e402..f27a38d8 100644 --- a/MVMCoreUI/BaseClasses/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -97,7 +97,7 @@ import UIKit // Ensures accessory view aligns to the center y derived from the if let _ = heroAccessoryCenter { - alignAccessoryToHero() + _ = alignAccessoryToHero() } } @@ -215,14 +215,16 @@ import UIKit } /// NOTE: Should only be called when displayed or about to be displayed. - public func alignAccessoryToHero() { + public func alignAccessoryToHero() -> CGPoint? { // Layout call required to force draw in memory to get dimensions of subviews. layoutIfNeeded() - guard let heroLabel = findHeroLabel(views: contentView.subviews), let hero = heroLabel.hero else { return } + guard let heroLabel = findHeroLabel(views: contentView.subviews), let hero = heroLabel.hero else { return nil } let rect = Label.boundingRect(forCharacterRange: NSRange(location: hero, length: 1), in: heroLabel) - accessoryView?.center.y = convert(UIView(frame: rect).center, from: heroLabel).y + let y = convert(UIView(frame: rect).center, from: heroLabel).y + accessoryView?.center.y = y heroAccessoryCenter = accessoryView?.center + return heroAccessoryCenter ?? CGPoint(x: 0, y: y) } /// Traverses the view hierarchy for a 🦸‍♂️ heroic Label. @@ -269,7 +271,7 @@ import UIKit } public func willDisplay() { - alignAccessoryToHero() + _ = alignAccessoryToHero() } // MARK: - Separator From 0bfd72f38443110bba60b41fbfc37cbc87abcbae Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Sat, 18 Apr 2020 19:10:15 -0400 Subject: [PATCH 34/34] recorder --- MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 3aff695d..bebdd424 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -139,11 +139,10 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonBodyText.self, viewModelClass: ListLeftVariableRadioButtonBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self) - MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeBodyText.self, viewModelClass: ListRightVariablePriceChangeBodyTextModel.self) - MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTotalData.self, viewModelClass: ListRightVariableTotalDataModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTextLinkAllTextAndLinks.self, viewModelClass: ListRightVariableTextLinkAllTextAndLinksModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableButtonAllTextAndLinks.self, viewModelClass: ListRightVariableButtonAllTextAndLinksModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeBodyText.self, viewModelClass: ListRightVariablePriceChangeBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeAllTextAndLinks.self, viewModelClass: ListRightVariablePriceChangeAllTextAndLinksModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextAllTextAndLinks.self, viewModelClass: ListOneColumnFullWidthTextAllTextAndLinksModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextBodyText.self, viewModelClass: ListOneColumnFullWidthTextBodyTextModel.self)