From 3b8fd4167c523137b8465046fceef7159a19933b Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Wed, 1 Apr 2020 19:27:18 +0530 Subject: [PATCH 01/13] initial commit --- MVMCoreUI.xcodeproj/project.pbxproj | 16 +++ .../Views/RadioBoxCollectionViewCell.swift | 87 +++++++++++++ .../Atomic/Atoms/Views/RadioBoxModel.swift | 54 ++++++++ MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift | 122 ++++++++++++++++++ .../Atomic/Atoms/Views/RadioBoxesModel.swift | 57 ++++++++ MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 2 + 6 files changed, 338 insertions(+) create mode 100644 MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift create mode 100644 MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift create mode 100644 MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift create mode 100644 MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 03335a4d..df815789 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -173,8 +173,12 @@ 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 */; }; + BB2C969424331C46006FF80C /* RadioBoxes.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C969324331C46006FF80C /* RadioBoxes.swift */; }; + BB2C969624331C74006FF80C /* RadioBoxesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C969524331C74006FF80C /* RadioBoxesModel.swift */; }; + BB2C969824331F8E006FF80C /* RadioBoxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C969724331F8E006FF80C /* RadioBoxModel.swift */; }; BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */; }; BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */; }; + BB54C519243459280038326C /* RadioBoxCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB54C518243459280038326C /* RadioBoxCollectionViewCell.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 */; }; @@ -556,8 +560,12 @@ 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 = ""; }; + BB2C969324331C46006FF80C /* RadioBoxes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBoxes.swift; sourceTree = ""; }; + BB2C969524331C74006FF80C /* RadioBoxesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBoxesModel.swift; sourceTree = ""; }; + BB2C969724331F8E006FF80C /* RadioBoxModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBoxModel.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 = ""; }; + BB54C518243459280038326C /* RadioBoxCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBoxCollectionViewCell.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 = ""; }; @@ -1499,6 +1507,10 @@ D29DF17D21E69E26003B2FB9 /* Views */ = { isa = PBXGroup; children = ( + BB2C969324331C46006FF80C /* RadioBoxes.swift */, + BB54C518243459280038326C /* RadioBoxCollectionViewCell.swift */, + BB2C969524331C74006FF80C /* RadioBoxesModel.swift */, + BB2C969724331F8E006FF80C /* RadioBoxModel.swift */, 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */, 01509D922327ECFB00EF99AA /* ProgressBar.swift */, 9445890D2385C3F800DE9FD4 /* MultiProgressModel.swift */, @@ -2079,8 +2091,10 @@ D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */, AAA74A172410C04600080241 /* HeadersH2NoButtonsBodyText.swift in Sources */, 522679C223FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift in Sources */, + BB2C969424331C46006FF80C /* RadioBoxes.swift in Sources */, 8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */, 0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */, + BB2C969624331C74006FF80C /* RadioBoxesModel.swift in Sources */, 8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */, D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */, 525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */, @@ -2132,6 +2146,7 @@ 011D95A1240453D0000E3791 /* RuleEqualsModel.swift in Sources */, D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */, 011D95892404249B000E3791 /* FormHolderModelProtocol.swift in Sources */, + BB2C969824331F8E006FF80C /* RadioBoxModel.swift in Sources */, 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */, 013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */, 525239C22407BD1000454969 /* ListTwoColumnPriceDetails.swift in Sources */, @@ -2160,6 +2175,7 @@ 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */, D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */, D2B18B922361E65A00A9AEDC /* CoreUIObject.swift in Sources */, + BB54C519243459280038326C /* RadioBoxCollectionViewCell.swift in Sources */, D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */, 014AA72E23C5059B006F3E93 /* StackCenteredPageTemplateModel.swift in Sources */, D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift new file mode 100644 index 00000000..532ff34f --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift @@ -0,0 +1,87 @@ +// +// RadioBoxCollectionViewCell.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 01/04/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtocol { + + public let bodyLabel = Label.commonLabelB2(true) + public let lineView = View(frame: .zero) + + + var bottomView = MVMCoreUICommonViewsUtility.commonView() + + public var lineViewHeight: NSLayoutConstraint? + + + open override var isSelected: Bool{ + didSet{ + lineViewHeight?.constant = isSelected ? 4.0 : 0 + bottomView.layer.borderColor = isSelected ? UIColor.mfGet(forHex: "#0000").cgColor:UIColor.mfGet(forHex: "#747676").cgColor + + } + } + public override init(frame: CGRect) { + super.init(frame: .zero) + setupView() + } + + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setupView() + } + + public func setupView() { + guard bottomView.superview == nil else { + return + } + isAccessibilityElement = false + contentView.isAccessibilityElement = false + insetsLayoutMarginsFromSafeArea = false + contentView.insetsLayoutMarginsFromSafeArea = false + contentView.preservesSuperviewLayoutMargins = false + + contentView.addSubview(bottomView) + NSLayoutConstraint.constraintPinSubview(toSuperview: bottomView) + + lineView.translatesAutoresizingMaskIntoConstraints = false + bottomView.addSubview(lineView) + NSLayoutConstraint.constraintPinSubview(lineView, pinTop: true, pinBottom: false, pinLeft: true, pinRight: true) + lineViewHeight = lineView.heightAnchor.constraint(equalToConstant: 0) + lineViewHeight?.isActive = true + + + bodyLabel.translatesAutoresizingMaskIntoConstraints = false + bottomView.addSubview(bodyLabel) + NSLayoutConstraint.constraintPinSubview(bodyLabel, pinTop: false, topConstant:0 , pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: 12, pinRight: true, rightConstant: 12) + bodyLabel.topAnchor.constraint(equalTo: lineView.bottomAnchor, constant: 12).isActive = true + bodyLabel.bottomAnchor.constraint(greaterThanOrEqualTo: bottomView.bottomAnchor, constant: -12.0).isActive = true + + bottomView.layer.borderWidth = 1.0 + bottomView.layer.borderColor = UIColor.mfGet(forHex: "#747676").cgColor + + + + } + + + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + guard let collectionModel = model as? RadioBoxModel else { return } + + if let backgroundColor = collectionModel.backgroundColor { + self.bottomView.backgroundColor = backgroundColor.uiColor + } +// self.bottomView.backgroundColor = .red + lineView.backgroundColor = collectionModel.selectedAccentColor?.uiColor + bodyLabel.text = collectionModel.text + + + + } + + +} diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift new file mode 100644 index 00000000..21adcb13 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift @@ -0,0 +1,54 @@ +// +// RadioBoxModel.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 31/03/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +@objcMembers public class RadioBoxModel: MoleculeModelProtocol { + public static var identifier: String = "radioBox" + public var text: String + public var backgroundColor: Color? = Color(uiColor: .white) + public var selectedAccentColor: Color? = Color(uiColor: .red) + public var selected: Bool? = false + public var fieldValue: String? + + private enum CodingKeys: String, CodingKey { + case moleculeName + case text + case selectedAccentColor + case backgroundColor + case selected + case fieldValue + + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + text = try typeContainer.decode(String.self, forKey: .text) + + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor) { + selectedAccentColor = color + } + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) { + backgroundColor = color + } + if let isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) { + selected = isSelected + } + 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.encode(selectedAccentColor, forKey: .selectedAccentColor) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(selected, forKey: .selected) + try container.encodeIfPresent(fieldValue, forKey: .fieldValue) + + } +} diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift new file mode 100644 index 00000000..9cc6ae5f --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift @@ -0,0 +1,122 @@ +// +// RadioBoxes.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 31/03/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +open class RadioBoxes: View { + + public let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + + /// The models for the molecules. + var molecules: [MoleculeModelProtocol]? + + + /// The height of the carousel. Default is 300. + public var collectionViewHeight: NSLayoutConstraint? + + public var delegateObject: MVMCoreUIDelegateObject? + + + + // MARK: - MVMCoreViewProtocol + 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) + + collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 300) + collectionViewHeight?.isActive = true + NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView) + + } + + + + // MARK: - MoleculeViewProtocol + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + self.delegateObject = delegateObject + super.set(with: model, delegateObject, additionalData) + guard let radioBoxesModel = model as? RadioBoxesModel else { return } + backgroundColor = .white + + registerCells() + setupLayout(with: radioBoxesModel) + prepareMolecules(with: radioBoxesModel) + collectionView.reloadData() + } + + // MARK: - JSON Setters + /// Updates the layout being used + + func setupLayout(with carouselModel: RadioBoxesModel?) { + let layout = UICollectionViewFlowLayout() + layout.scrollDirection = .vertical + layout.minimumLineSpacing = 10 + layout.minimumInteritemSpacing = 10 + collectionView.collectionViewLayout = layout + } + + func prepareMolecules(with radioBoxesModel: RadioBoxesModel?) { + guard let newMolecules = radioBoxesModel?.boxes else { + molecules = nil + return + } + molecules = newMolecules + collectionView.reloadData() + + } + + + /// Registers the cells with the collection view + func registerCells() { + + collectionView.register(RadioBoxCollectionViewCell.self, forCellWithReuseIdentifier: "RadioBoxCollectionViewCell") + } + + + // MARK: - Convenience + /// Returns the (identifier, class) of the molecule for the given map. + func getMoleculeInfo(with molecule: MoleculeModelProtocol, delegateObject: MVMCoreUIDelegateObject?) -> (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)? { + guard let className = MoleculeObjectMapping.shared()?.getMoleculeClass(molecule) else { + return nil + } + return (className.nameForReuse(with: molecule, delegateObject) ?? molecule.moleculeName, className, molecule) + } + + +} +extension RadioBoxes: UICollectionViewDelegateFlowLayout { + open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + let itemWidth = (collectionView.bounds.width - 30)/2 + return CGSize(width: itemWidth, height: 64) + } + + +} + +extension RadioBoxes: UICollectionViewDataSource { + open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return molecules?.count ?? 0 + } + + open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + guard let molecule = molecules?[indexPath.row], let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioBoxCollectionViewCell", for: indexPath) as? RadioBoxCollectionViewCell else { + return UICollectionViewCell() + } + cell.set(with: molecule, delegateObject, nil) + (cell as? MVMCoreViewProtocol)?.updateView(collectionView.bounds.width) + return cell + } +} diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift new file mode 100644 index 00000000..80425bde --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift @@ -0,0 +1,57 @@ +// +// RadioBoxesModel.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 31/03/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation +@objcMembers public class RadioBoxesModel: MoleculeModelProtocol { + public static var identifier: String = "radioBoxes" + public var backgroundColor: Color? = Color(uiColor: .white) + public var selectedAccentColor: Color? = Color(uiColor: .red) + public var enabled: Bool? = true + public var boxes: [RadioBoxModel] + public var fieldKey: String? + public var groupName: String? + + private enum CodingKeys: String, CodingKey { + case moleculeName + case selectedAccentColor + case backgroundColor + case enabled + case boxes + case fieldKey + case groupName + + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor) { + selectedAccentColor = color + } + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) { + backgroundColor = color + } + if let isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { + enabled = isEnabled + } + boxes = try typeContainer.decode([RadioBoxModel].self, forKey: .boxes) + fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) + groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) + + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(selectedAccentColor, forKey: .selectedAccentColor) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(enabled, forKey: .enabled) + try container.encodeIfPresent(fieldKey, forKey: .fieldKey) + try container.encodeIfPresent(groupName, forKey: .groupName) + + } +} diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index bfa6db01..f0ea8a63 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -67,6 +67,8 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: DateDropdownEntryField.self, viewModelClass: DateDropdownEntryFieldModel.self) // Other Atoms + MoleculeObjectMapping.shared()?.register(viewClass: RadioBoxes.self, viewModelClass: RadioBoxesModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self) MoleculeObjectMapping.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self) MoleculeObjectMapping.shared()?.register(viewClass: CaretView.self, viewModelClass: CaretViewModel.self) From 96115b7a5da4f8ef79d07ff76c0f8981a18629d1 Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Fri, 3 Apr 2020 12:45:32 +0530 Subject: [PATCH 02/13] border changes updated --- .../Views/RadioBoxCollectionViewCell.swift | 82 +++++++++++++------ .../Atomic/Atoms/Views/RadioBoxModel.swift | 8 +- MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift | 73 ++++++++--------- .../Atomic/Atoms/Views/RadioBoxesModel.swift | 1 - 4 files changed, 96 insertions(+), 68 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift index 532ff34f..c709cf4b 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift @@ -8,28 +8,37 @@ import Foundation open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtocol { - + public let bodyLabel = Label.commonLabelB2(true) public let lineView = View(frame: .zero) - - var bottomView = MVMCoreUICommonViewsUtility.commonView() - public var lineViewHeight: NSLayoutConstraint? + public var fieldValue: String? open override var isSelected: Bool{ didSet{ - lineViewHeight?.constant = isSelected ? 4.0 : 0 - bottomView.layer.borderColor = isSelected ? UIColor.mfGet(forHex: "#0000").cgColor:UIColor.mfGet(forHex: "#747676").cgColor - + self.lineViewHeight?.constant = self.isSelected ? 4.0 : 0 + self.bottomView.layer.sublayers?.filter({$0.name == "border"}).forEach({$0.removeFromSuperlayer()}) + if(self.isSelected){ + self.bottomView.layer.addBorder(edge: .bottom, color: UIColor.mfGet(forHex: "#0000"), thickness: 1.0) + self.bottomView.layer.addBorder(edge: .left, color: UIColor.mfGet(forHex: "#0000"), thickness: 1.0) + self.bottomView.layer.addBorder(edge: .right, color: UIColor.mfGet(forHex: "#0000"), thickness: 1.0) + } + else { + self.addBordertoView() + } } } public override init(frame: CGRect) { super.init(frame: .zero) setupView() } - + open override func layoutSubviews() { + super.layoutSubviews() + addBordertoView() + + } public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setupView() @@ -44,7 +53,6 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco insetsLayoutMarginsFromSafeArea = false contentView.insetsLayoutMarginsFromSafeArea = false contentView.preservesSuperviewLayoutMargins = false - contentView.addSubview(bottomView) NSLayoutConstraint.constraintPinSubview(toSuperview: bottomView) @@ -54,34 +62,58 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco lineViewHeight = lineView.heightAnchor.constraint(equalToConstant: 0) lineViewHeight?.isActive = true - bodyLabel.translatesAutoresizingMaskIntoConstraints = false + bodyLabel.numberOfLines = 0 bottomView.addSubview(bodyLabel) NSLayoutConstraint.constraintPinSubview(bodyLabel, pinTop: false, topConstant:0 , pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: 12, pinRight: true, rightConstant: 12) bodyLabel.topAnchor.constraint(equalTo: lineView.bottomAnchor, constant: 12).isActive = true - bodyLabel.bottomAnchor.constraint(greaterThanOrEqualTo: bottomView.bottomAnchor, constant: -12.0).isActive = true - - bottomView.layer.borderWidth = 1.0 - bottomView.layer.borderColor = UIColor.mfGet(forHex: "#747676").cgColor - - + bodyLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomView.bottomAnchor, constant: -12.0).isActive = true } - - + private func addBordertoView(){ + bottomView.layer.addBorder(edge: .bottom, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) + bottomView.layer.addBorder(edge: .left, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) + bottomView.layer.addBorder(edge: .right, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) + bottomView.layer.addBorder(edge: .top, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) + } + + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let collectionModel = model as? RadioBoxModel else { return } - if let backgroundColor = collectionModel.backgroundColor { self.bottomView.backgroundColor = backgroundColor.uiColor } -// self.bottomView.backgroundColor = .red lineView.backgroundColor = collectionModel.selectedAccentColor?.uiColor bodyLabel.text = collectionModel.text - - - + isSelected = collectionModel.selected ?? false + fieldValue = collectionModel.fieldValue } - - +} +extension CALayer { + + func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) { + + let border = CALayer() + border.name = "border" + switch edge { + case UIRectEdge.top: + border.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: thickness) + break + case UIRectEdge.bottom: + border.frame = CGRect(x: 0, y: self.frame.height - thickness, width: self.frame.width, height: thickness) + break + case UIRectEdge.left: + border.frame = CGRect(x: 0, y: 0, width: thickness, height: self.frame.height) + break + case UIRectEdge.right: + border.frame = CGRect(x: self.frame.width - thickness, y: 0, width: thickness, height: self.frame.height) + break + default: + break + } + + border.backgroundColor = color.cgColor; + self.addSublayer(border) + } + } diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift index 21adcb13..0e72f6e5 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift @@ -11,8 +11,9 @@ import Foundation public static var identifier: String = "radioBox" public var text: String public var backgroundColor: Color? = Color(uiColor: .white) - public var selectedAccentColor: Color? = Color(uiColor: .red) + public var selectedAccentColor: Color? = try? Color(colorString: "#D52B1E") public var selected: Bool? = false + public var strikethrough: Bool? = false public var fieldValue: String? private enum CodingKeys: String, CodingKey { @@ -21,6 +22,7 @@ import Foundation case selectedAccentColor case backgroundColor case selected + case strikethrough case fieldValue } @@ -38,6 +40,9 @@ import Foundation if let isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) { selected = isSelected } + if let isStrikeTrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) { + strikethrough = isStrikeTrough + } fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue) } @@ -48,6 +53,7 @@ import Foundation try container.encode(selectedAccentColor, forKey: .selectedAccentColor) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(selected, forKey: .selected) + try container.encodeIfPresent(strikethrough, forKey: .strikethrough) try container.encodeIfPresent(fieldValue, forKey: .fieldValue) } diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift index 9cc6ae5f..39f03c40 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift @@ -7,21 +7,23 @@ // import Foundation -open class RadioBoxes: View { +open class RadioBoxes: View { + public let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) /// The models for the molecules. - var molecules: [MoleculeModelProtocol]? + var boxes: [RadioBoxModel]? + public var fieldKey: String? + public var groupName: String? + public var enabled: Bool? - - /// The height of the carousel. Default is 300. public var collectionViewHeight: NSLayoutConstraint? - - public var delegateObject: MVMCoreUIDelegateObject? + private let boxWidth: Double = 151.0 + private let boxHeight: Double = 64.0 + private let itemSpacing: Double = 10.0 + private let leadingSpacing: Double = 0 - - // MARK: - MVMCoreViewProtocol open override func setupView() { super.setupView() @@ -35,22 +37,21 @@ open class RadioBoxes: View { collectionView.backgroundColor = .clear collectionView.isAccessibilityElement = false addSubview(collectionView) - + NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView) collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 300) collectionViewHeight?.isActive = true - NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView) - + } - // MARK: - MoleculeViewProtocol public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - self.delegateObject = delegateObject super.set(with: model, delegateObject, additionalData) guard let radioBoxesModel = model as? RadioBoxesModel else { return } - backgroundColor = .white - + backgroundColor = radioBoxesModel.backgroundColor?.uiColor + fieldKey = radioBoxesModel.fieldKey + groupName = radioBoxesModel.groupName + enabled = radioBoxesModel.enabled registerCells() setupLayout(with: radioBoxesModel) prepareMolecules(with: radioBoxesModel) @@ -59,64 +60,54 @@ open class RadioBoxes: View { // MARK: - JSON Setters /// Updates the layout being used - + func setupLayout(with carouselModel: RadioBoxesModel?) { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .vertical + layout.sectionInset = UIEdgeInsets.init(top: CGFloat(leadingSpacing), left: CGFloat(leadingSpacing), bottom: CGFloat(leadingSpacing), right: CGFloat(leadingSpacing)) layout.minimumLineSpacing = 10 layout.minimumInteritemSpacing = 10 collectionView.collectionViewLayout = layout } - + func prepareMolecules(with radioBoxesModel: RadioBoxesModel?) { guard let newMolecules = radioBoxesModel?.boxes else { - molecules = nil + boxes = nil return } - molecules = newMolecules - collectionView.reloadData() - + boxes = newMolecules + let height = Double(round(Double((boxes?.count ?? Int(0.0)))/2.0))*(boxHeight+10.0) + collectionViewHeight?.constant = CGFloat(height) + collectionViewHeight?.isActive = true } - - + /// Registers the cells with the collection view func registerCells() { collectionView.register(RadioBoxCollectionViewCell.self, forCellWithReuseIdentifier: "RadioBoxCollectionViewCell") } - - - // MARK: - Convenience - /// Returns the (identifier, class) of the molecule for the given map. - func getMoleculeInfo(with molecule: MoleculeModelProtocol, delegateObject: MVMCoreUIDelegateObject?) -> (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)? { - guard let className = MoleculeObjectMapping.shared()?.getMoleculeClass(molecule) else { - return nil - } - return (className.nameForReuse(with: molecule, delegateObject) ?? molecule.moleculeName, className, molecule) - } } extension RadioBoxes: UICollectionViewDelegateFlowLayout { open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { - let itemWidth = (collectionView.bounds.width - 30)/2 - return CGSize(width: itemWidth, height: 64) + let itemWidth = (Double(collectionView.bounds.width) - itemSpacing)/2 + return CGSize(width: CGFloat(150.5), height: CGFloat(boxHeight)) } - - } extension RadioBoxes: UICollectionViewDataSource { open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - return molecules?.count ?? 0 + return boxes?.count ?? 0 } open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - guard let molecule = molecules?[indexPath.row], let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioBoxCollectionViewCell", for: indexPath) as? RadioBoxCollectionViewCell else { - return UICollectionViewCell() + guard let molecule = boxes?[indexPath.row], let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioBoxCollectionViewCell", for: indexPath) as? RadioBoxCollectionViewCell else { + return UICollectionViewCell() } - cell.set(with: molecule, delegateObject, nil) + cell.set(with: molecule, nil, nil) (cell as? MVMCoreViewProtocol)?.updateView(collectionView.bounds.width) + cell.layoutIfNeeded() return cell } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift index 80425bde..ab2b4728 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift @@ -24,7 +24,6 @@ import Foundation case boxes case fieldKey case groupName - } required public init(from decoder: Decoder) throws { From ade0e043a4822cb3ca28cc8087cc09d5c5a1fbfb Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Tue, 7 Apr 2020 07:51:44 +0530 Subject: [PATCH 03/13] fixed box sizes issues --- .../Views/RadioBoxCollectionViewCell.swift | 54 ++++++++++++++++--- MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift | 18 +++++-- 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift index c709cf4b..f29c6bb1 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift @@ -14,11 +14,14 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco var bottomView = MVMCoreUICommonViewsUtility.commonView() public var lineViewHeight: NSLayoutConstraint? public var fieldValue: String? - + open override var isSelected: Bool{ didSet{ self.lineViewHeight?.constant = self.isSelected ? 4.0 : 0 + UIView.animate(withDuration: 0.5) { + self.layoutIfNeeded() + } self.bottomView.layer.sublayers?.filter({$0.name == "border"}).forEach({$0.removeFromSuperlayer()}) if(self.isSelected){ self.bottomView.layer.addBorder(edge: .bottom, color: UIColor.mfGet(forHex: "#0000"), thickness: 1.0) @@ -30,15 +33,23 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco } } } + var isOutofStock: Bool = false{ + didSet{ + DispatchQueue.main.async { [weak self] in + guard let strongSelf = self else { + return + } + strongSelf.bottomView.layer.sublayers?.filter({$0.name == "outofstock"}).forEach({$0.removeFromSuperlayer()}) + if(strongSelf.isOutofStock){ + strongSelf.addOutofstockLine() + } + } + } + } public override init(frame: CGRect) { super.init(frame: .zero) setupView() } - open override func layoutSubviews() { - super.layoutSubviews() - addBordertoView() - - } public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setupView() @@ -53,6 +64,7 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco insetsLayoutMarginsFromSafeArea = false contentView.insetsLayoutMarginsFromSafeArea = false contentView.preservesSuperviewLayoutMargins = false + bottomView.translatesAutoresizingMaskIntoConstraints = false contentView.addSubview(bottomView) NSLayoutConstraint.constraintPinSubview(toSuperview: bottomView) @@ -70,25 +82,51 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco bodyLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomView.bottomAnchor, constant: -12.0).isActive = true } + public func updateView(_ size: CGFloat) { + self.setNeedsLayout() + self.bottomView.setNeedsLayout() + self.bottomView.layer.sublayers?.filter({$0.name == "border"}).forEach({$0.removeFromSuperlayer()}) + DispatchQueue.main.async { [weak self] in + self?.addBordertoView() + } + + } + + + private func addBordertoView(){ bottomView.layer.addBorder(edge: .bottom, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) bottomView.layer.addBorder(edge: .left, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) bottomView.layer.addBorder(edge: .right, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) bottomView.layer.addBorder(edge: .top, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) } - + private func addOutofstockLine(){ + + let path = UIBezierPath() + path.move(to: CGPoint(x: 0, y: bottomView.bounds.height)) + path.addLine(to: CGPoint(x: bottomView.bounds.width, y: 0)) + + let shapeLayer = CAShapeLayer() + shapeLayer.name = "outofstock" + shapeLayer.path = path.cgPath + shapeLayer.strokeColor = UIColor.darkGray.cgColor + shapeLayer.lineWidth = 0.5 + bottomView.layer.addSublayer(shapeLayer) + } public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let collectionModel = model as? RadioBoxModel else { return } if let backgroundColor = collectionModel.backgroundColor { - self.bottomView.backgroundColor = backgroundColor.uiColor + bottomView.backgroundColor = backgroundColor.uiColor } lineView.backgroundColor = collectionModel.selectedAccentColor?.uiColor bodyLabel.text = collectionModel.text isSelected = collectionModel.selected ?? false fieldValue = collectionModel.fieldValue + isOutofStock = collectionModel.strikethrough ?? false } } + extension CALayer { func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) { diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift index 39f03c40..7dcd2acc 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift @@ -57,11 +57,23 @@ open class RadioBoxes: View { prepareMolecules(with: radioBoxesModel) collectionView.reloadData() } + @objc override open func updateView(_ size: CGFloat) { + + collectionView.collectionViewLayout.invalidateLayout() + + DispatchQueue.main.async { [weak self] in + self?.setNeedsDisplay() + self?.collectionView.layoutIfNeeded() + self?.collectionView.reloadData() + + } + } + // MARK: - JSON Setters /// Updates the layout being used - func setupLayout(with carouselModel: RadioBoxesModel?) { + func setupLayout(with radioBoxesModel: RadioBoxesModel?) { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .vertical layout.sectionInset = UIEdgeInsets.init(top: CGFloat(leadingSpacing), left: CGFloat(leadingSpacing), bottom: CGFloat(leadingSpacing), right: CGFloat(leadingSpacing)) @@ -92,7 +104,7 @@ open class RadioBoxes: View { extension RadioBoxes: UICollectionViewDelegateFlowLayout { open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let itemWidth = (Double(collectionView.bounds.width) - itemSpacing)/2 - return CGSize(width: CGFloat(150.5), height: CGFloat(boxHeight)) + return CGSize(width: CGFloat(itemWidth), height: CGFloat(boxHeight)) } } @@ -106,7 +118,7 @@ extension RadioBoxes: UICollectionViewDataSource { return UICollectionViewCell() } cell.set(with: molecule, nil, nil) - (cell as? MVMCoreViewProtocol)?.updateView(collectionView.bounds.width) + cell.updateView(collectionView.bounds.width) cell.layoutIfNeeded() return cell } From ced8dd54e194f57e1cfae378c97d0ef7c20939df Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Tue, 7 Apr 2020 15:30:42 +0530 Subject: [PATCH 04/13] file paths added --- MVMCoreUI.xcodeproj/project.pbxproj | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index c0a56ebc..65c8b408 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -192,6 +192,10 @@ BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6ABF242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift */; }; BB6C6AC824225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6AC62422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift */; }; BB6C6AC924225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6AC72422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift */; }; + BBA326A9243C85550011D1F6 /* RadioBoxesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBA326A5243C85540011D1F6 /* RadioBoxesModel.swift */; }; + BBA326AA243C85550011D1F6 /* RadioBoxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBA326A6243C85540011D1F6 /* RadioBoxModel.swift */; }; + BBA326AB243C85550011D1F6 /* RadioBoxCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBA326A7243C85540011D1F6 /* RadioBoxCollectionViewCell.swift */; }; + BBA326AC243C85550011D1F6 /* RadioBoxes.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBA326A8243C85550011D1F6 /* RadioBoxes.swift */; }; C003506123AA94CD00B6AC29 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = C003506023AA94CD00B6AC29 /* Button.swift */; }; C07065C42395677300FBF997 /* Link.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07065C32395677300FBF997 /* Link.swift */; }; C695A67F23C9830600BFB94E /* UnOrderedListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */; }; @@ -590,6 +594,10 @@ 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 = ""; }; BB6C6AC72422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerShortModel.swift; sourceTree = ""; }; + BBA326A5243C85540011D1F6 /* RadioBoxesModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxesModel.swift; sourceTree = ""; }; + BBA326A6243C85540011D1F6 /* RadioBoxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxModel.swift; sourceTree = ""; }; + BBA326A7243C85540011D1F6 /* RadioBoxCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxCollectionViewCell.swift; sourceTree = ""; }; + BBA326A8243C85550011D1F6 /* RadioBoxes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxes.swift; sourceTree = ""; }; C003506023AA94CD00B6AC29 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = ""; }; C07065C32395677300FBF997 /* Link.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Link.swift; sourceTree = ""; }; C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnOrderedListModel.swift; sourceTree = ""; }; @@ -1566,6 +1574,10 @@ D29DF17D21E69E26003B2FB9 /* Views */ = { isa = PBXGroup; children = ( + BBA326A5243C85540011D1F6 /* RadioBoxesModel.swift */, + BBA326A8243C85550011D1F6 /* RadioBoxes.swift */, + BBA326A6243C85540011D1F6 /* RadioBoxModel.swift */, + BBA326A7243C85540011D1F6 /* RadioBoxCollectionViewCell.swift */, 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */, 01509D922327ECFB00EF99AA /* ProgressBar.swift */, 9445890D2385C3F800DE9FD4 /* MultiProgressModel.swift */, @@ -1986,6 +1998,7 @@ D2B18B7F2360913400A9AEDC /* Control.swift in Sources */, 011D95A924057AC7000E3791 /* FormGroupWatcherFieldProtocol.swift in Sources */, D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */, + BBA326AC243C85550011D1F6 /* RadioBoxes.swift in Sources */, 0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */, D29DF12F21E6851E003B2FB9 /* MVMCoreUITopAlertMainView.m in Sources */, 942C378C2412F4FA0066E45E /* ModalMoleculeListTemplate.swift in Sources */, @@ -2038,6 +2051,7 @@ D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */, D202AFE6242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift in Sources */, 8D084AD22410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift in Sources */, + BBA326AB243C85550011D1F6 /* RadioBoxCollectionViewCell.swift in Sources */, 94C0150C2421564A005811A9 /* ActionCollapseNotificationModel.swift in Sources */, 014AA73123C5059B006F3E93 /* ListPageTemplateModel.swift in Sources */, D29DF2A221E7AF4E003B2FB9 /* MVMCoreUIUtility.m in Sources */, @@ -2085,6 +2099,7 @@ D2B18B812360945C00A9AEDC /* View.swift in Sources */, C6FA7D5423C77A4A00A3614A /* NumberedList.swift in Sources */, D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */, + BBA326A9243C85550011D1F6 /* RadioBoxesModel.swift in Sources */, 525019E52406852100EED91C /* ListFourColumnDataUsageDividerModel.swift in Sources */, 0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */, 94FB966323D797DA003D482B /* MFTextButton.m in Sources */, @@ -2243,6 +2258,7 @@ D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */, 014AA72E23C5059B006F3E93 /* StackCenteredPageTemplateModel.swift in Sources */, D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */, + BBA326AA243C85550011D1F6 /* RadioBoxModel.swift in Sources */, 011D959D2404536F000E3791 /* RuleAnyValueChangedModel.swift in Sources */, D260105923D0A92900764D80 /* ContainerProtocol.swift in Sources */, BB6C6AC924225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift in Sources */, From f251b550047d6085754a5868503471e90484efa0 Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Tue, 7 Apr 2020 19:15:10 +0530 Subject: [PATCH 05/13] alignment changes --- .../Views/RadioBoxCollectionViewCell.swift | 39 ++++++++----------- .../Atomic/Atoms/Views/RadioBoxModel.swift | 16 ++++---- MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift | 14 +------ .../Atomic/Atoms/Views/RadioBoxesModel.swift | 10 +---- 4 files changed, 29 insertions(+), 50 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift index f29c6bb1..67068c85 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift @@ -15,7 +15,6 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco public var lineViewHeight: NSLayoutConstraint? public var fieldValue: String? - open override var isSelected: Bool{ didSet{ self.lineViewHeight?.constant = self.isSelected ? 4.0 : 0 @@ -33,23 +32,24 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco } } } - var isOutofStock: Bool = false{ + + var isOutOfStock: Bool = false { didSet{ DispatchQueue.main.async { [weak self] in - guard let strongSelf = self else { - return - } - strongSelf.bottomView.layer.sublayers?.filter({$0.name == "outofstock"}).forEach({$0.removeFromSuperlayer()}) - if(strongSelf.isOutofStock){ - strongSelf.addOutofstockLine() + guard let self = self else { return } + self.bottomView.layer.sublayers?.filter({$0.name == "outofstock"}).forEach({$0.removeFromSuperlayer()}) + if(self.isOutOfStock) { + self.addOutOfStockLine() } } } } + public override init(frame: CGRect) { super.init(frame: .zero) setupView() } + public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setupView() @@ -68,20 +68,18 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco contentView.addSubview(bottomView) NSLayoutConstraint.constraintPinSubview(toSuperview: bottomView) - lineView.translatesAutoresizingMaskIntoConstraints = false bottomView.addSubview(lineView) NSLayoutConstraint.constraintPinSubview(lineView, pinTop: true, pinBottom: false, pinLeft: true, pinRight: true) lineViewHeight = lineView.heightAnchor.constraint(equalToConstant: 0) lineViewHeight?.isActive = true - bodyLabel.translatesAutoresizingMaskIntoConstraints = false - bodyLabel.numberOfLines = 0 + bodyLabel.numberOfLines = 1 bottomView.addSubview(bodyLabel) NSLayoutConstraint.constraintPinSubview(bodyLabel, pinTop: false, topConstant:0 , pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: 12, pinRight: true, rightConstant: 12) bodyLabel.topAnchor.constraint(equalTo: lineView.bottomAnchor, constant: 12).isActive = true bodyLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomView.bottomAnchor, constant: -12.0).isActive = true - } + public func updateView(_ size: CGFloat) { self.setNeedsLayout() self.bottomView.setNeedsLayout() @@ -89,23 +87,19 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco DispatchQueue.main.async { [weak self] in self?.addBordertoView() } - } - - - + private func addBordertoView(){ bottomView.layer.addBorder(edge: .bottom, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) bottomView.layer.addBorder(edge: .left, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) bottomView.layer.addBorder(edge: .right, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) bottomView.layer.addBorder(edge: .top, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) } - private func addOutofstockLine(){ - + + private func addOutOfStockLine(){ let path = UIBezierPath() path.move(to: CGPoint(x: 0, y: bottomView.bounds.height)) path.addLine(to: CGPoint(x: bottomView.bounds.width, y: 0)) - let shapeLayer = CAShapeLayer() shapeLayer.name = "outofstock" shapeLayer.path = path.cgPath @@ -119,11 +113,13 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco if let backgroundColor = collectionModel.backgroundColor { bottomView.backgroundColor = backgroundColor.uiColor } + self.isUserInteractionEnabled = collectionModel.enabled lineView.backgroundColor = collectionModel.selectedAccentColor?.uiColor bodyLabel.text = collectionModel.text - isSelected = collectionModel.selected ?? false + isSelected = collectionModel.selected fieldValue = collectionModel.fieldValue - isOutofStock = collectionModel.strikethrough ?? false + isOutOfStock = collectionModel.strikethrough + } } @@ -153,5 +149,4 @@ extension CALayer { border.backgroundColor = color.cgColor; self.addSublayer(border) } - } diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift index 0e72f6e5..31f58e53 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift @@ -12,8 +12,9 @@ import Foundation public var text: String public var backgroundColor: Color? = Color(uiColor: .white) public var selectedAccentColor: Color? = try? Color(colorString: "#D52B1E") - public var selected: Bool? = false - public var strikethrough: Bool? = false + public var selected: Bool = false + public var enabled: Bool = true + public var strikethrough: Bool = false public var fieldValue: String? private enum CodingKeys: String, CodingKey { @@ -22,15 +23,14 @@ import Foundation case selectedAccentColor case backgroundColor case selected + case enabled case strikethrough case fieldValue - } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) text = try typeContainer.decode(String.self, forKey: .text) - if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor) { selectedAccentColor = color } @@ -40,21 +40,23 @@ import Foundation if let isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) { selected = isSelected } + if let isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { + enabled = isEnabled + } if let isStrikeTrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) { strikethrough = isStrikeTrough } 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.encode(selectedAccentColor, forKey: .selectedAccentColor) + try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(selected, forKey: .selected) + try container.encodeIfPresent(enabled, forKey: .enabled) try container.encodeIfPresent(strikethrough, forKey: .strikethrough) try container.encodeIfPresent(fieldValue, forKey: .fieldValue) - } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift index 7dcd2acc..90a0d684 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift @@ -16,8 +16,6 @@ open class RadioBoxes: View { var boxes: [RadioBoxModel]? public var fieldKey: String? public var groupName: String? - public var enabled: Bool? - public var collectionViewHeight: NSLayoutConstraint? private let boxWidth: Double = 151.0 private let boxHeight: Double = 64.0 @@ -40,10 +38,8 @@ open class RadioBoxes: View { NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView) collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 300) collectionViewHeight?.isActive = true - } - // MARK: - MoleculeViewProtocol public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) @@ -51,25 +47,21 @@ open class RadioBoxes: View { backgroundColor = radioBoxesModel.backgroundColor?.uiColor fieldKey = radioBoxesModel.fieldKey groupName = radioBoxesModel.groupName - enabled = radioBoxesModel.enabled registerCells() setupLayout(with: radioBoxesModel) prepareMolecules(with: radioBoxesModel) collectionView.reloadData() } + @objc override open func updateView(_ size: CGFloat) { - collectionView.collectionViewLayout.invalidateLayout() - DispatchQueue.main.async { [weak self] in self?.setNeedsDisplay() self?.collectionView.layoutIfNeeded() self?.collectionView.reloadData() - } } - // MARK: - JSON Setters /// Updates the layout being used @@ -95,12 +87,10 @@ open class RadioBoxes: View { /// Registers the cells with the collection view func registerCells() { - collectionView.register(RadioBoxCollectionViewCell.self, forCellWithReuseIdentifier: "RadioBoxCollectionViewCell") } - - } + extension RadioBoxes: UICollectionViewDelegateFlowLayout { open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let itemWidth = (Double(collectionView.bounds.width) - itemSpacing)/2 diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift index ab2b4728..4e690ffa 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift @@ -11,7 +11,6 @@ import Foundation public static var identifier: String = "radioBoxes" public var backgroundColor: Color? = Color(uiColor: .white) public var selectedAccentColor: Color? = Color(uiColor: .red) - public var enabled: Bool? = true public var boxes: [RadioBoxModel] public var fieldKey: String? public var groupName: String? @@ -20,7 +19,6 @@ import Foundation case moleculeName case selectedAccentColor case backgroundColor - case enabled case boxes case fieldKey case groupName @@ -34,23 +32,17 @@ import Foundation if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) { backgroundColor = color } - if let isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { - enabled = isEnabled - } boxes = try typeContainer.decode([RadioBoxModel].self, forKey: .boxes) fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) - } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) - try container.encode(selectedAccentColor, forKey: .selectedAccentColor) + try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) - try container.encodeIfPresent(enabled, forKey: .enabled) try container.encodeIfPresent(fieldKey, forKey: .fieldKey) try container.encodeIfPresent(groupName, forKey: .groupName) - } } From 88defbc75c32ad22eb63027860f0c547b119790d Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Wed, 8 Apr 2020 10:16:33 +0530 Subject: [PATCH 06/13] file paths added --- MVMCoreUI.xcodeproj/project.pbxproj | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 9516bdd3..d5abeb54 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -196,6 +196,10 @@ BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6ABF242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift */; }; BB6C6AC824225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6AC62422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift */; }; BB6C6AC924225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6AC72422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift */; }; + BBAA4F02243D8E3B005AAD5F /* RadioBoxCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBAA4EFE243D8E3A005AAD5F /* RadioBoxCollectionViewCell.swift */; }; + BBAA4F03243D8E3B005AAD5F /* RadioBoxes.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBAA4EFF243D8E3B005AAD5F /* RadioBoxes.swift */; }; + BBAA4F04243D8E3B005AAD5F /* RadioBoxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBAA4F00243D8E3B005AAD5F /* RadioBoxModel.swift */; }; + BBAA4F05243D8E3B005AAD5F /* RadioBoxesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBAA4F01243D8E3B005AAD5F /* RadioBoxesModel.swift */; }; BBBBC87C24374A4900B0F079 /* ListThreeColumnBillChangesDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBBC87A24374A4900B0F079 /* ListThreeColumnBillChangesDivider.swift */; }; BBBBC87D24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBBC87B24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift */; }; C003506123AA94CD00B6AC29 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = C003506023AA94CD00B6AC29 /* Button.swift */; }; @@ -600,6 +604,10 @@ 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 = ""; }; BB6C6AC72422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerShortModel.swift; sourceTree = ""; }; + BBAA4EFE243D8E3A005AAD5F /* RadioBoxCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxCollectionViewCell.swift; sourceTree = ""; }; + BBAA4EFF243D8E3B005AAD5F /* RadioBoxes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxes.swift; sourceTree = ""; }; + BBAA4F00243D8E3B005AAD5F /* RadioBoxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxModel.swift; sourceTree = ""; }; + BBAA4F01243D8E3B005AAD5F /* RadioBoxesModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxesModel.swift; sourceTree = ""; }; BBBBC87A24374A4900B0F079 /* ListThreeColumnBillChangesDivider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnBillChangesDivider.swift; sourceTree = ""; }; BBBBC87B24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListThreeColumnBillChangesDividerModel.swift; sourceTree = ""; }; C003506023AA94CD00B6AC29 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = ""; }; @@ -1584,6 +1592,10 @@ D29DF17D21E69E26003B2FB9 /* Views */ = { isa = PBXGroup; children = ( + BBAA4F01243D8E3B005AAD5F /* RadioBoxesModel.swift */, + BBAA4EFF243D8E3B005AAD5F /* RadioBoxes.swift */, + BBAA4F00243D8E3B005AAD5F /* RadioBoxModel.swift */, + BBAA4EFE243D8E3A005AAD5F /* RadioBoxCollectionViewCell.swift */, 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */, 01509D922327ECFB00EF99AA /* ProgressBar.swift */, 9445890D2385C3F800DE9FD4 /* MultiProgressModel.swift */, @@ -2041,6 +2053,7 @@ D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */, 014AA72F23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift in Sources */, 0A21DB91235E0EDB00C160A2 /* DigitBox.swift in Sources */, + BBAA4F04243D8E3B005AAD5F /* RadioBoxModel.swift in Sources */, D22D1F572204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m in Sources */, D28A838B23CCDA6B00DFE4FC /* ButtonModel.swift in Sources */, D2A5145F2211DDC100345BFB /* MoleculeStackView.swift in Sources */, @@ -2058,6 +2071,7 @@ 525239C02407BCFF00454969 /* ListTwoColumnPriceDetailsModel.swift in Sources */, D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */, D202AFE6242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift in Sources */, + BBAA4F02243D8E3B005AAD5F /* RadioBoxCollectionViewCell.swift in Sources */, 8D084AD22410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift in Sources */, 94C0150C2421564A005811A9 /* ActionCollapseNotificationModel.swift in Sources */, 014AA73123C5059B006F3E93 /* ListPageTemplateModel.swift in Sources */, @@ -2092,6 +2106,7 @@ 011D959B240451E3000E3791 /* RuleRequiredModel.swift in Sources */, 526A265C240D1FF700B0D828 /* ListTwoColumnCompareChangesModel.swift in Sources */, D2A92886241ACD99004E01C6 /* ProgrammaticTableViewController.swift in Sources */, + BBAA4F05243D8E3B005AAD5F /* RadioBoxesModel.swift in Sources */, 01509D952327ED1900EF99AA /* HeadlineBodyLinkToggle.swift in Sources */, 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */, D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */, @@ -2183,6 +2198,7 @@ 8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */, 0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */, 8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */, + BBAA4F03243D8E3B005AAD5F /* RadioBoxes.swift in Sources */, D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */, 525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */, 0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */, From 870658b4c1d9ddd6512a331e96563bf52ed6a9bf Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Wed, 8 Apr 2020 17:18:05 +0530 Subject: [PATCH 07/13] subtext label implemented --- .../Views/RadioBoxCollectionViewCell.swift | 47 +++++++++++++------ .../Atomic/Atoms/Views/RadioBoxModel.swift | 5 ++ MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift | 12 +++-- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift index 67068c85..d959285d 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift @@ -9,18 +9,20 @@ import Foundation open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtocol { - public let bodyLabel = Label.commonLabelB2(true) + public let bodyLabel = Label(frame: .zero) + public let subTextLabel = Label(frame: .zero) public let lineView = View(frame: .zero) var bottomView = MVMCoreUICommonViewsUtility.commonView() public var lineViewHeight: NSLayoutConstraint? public var fieldValue: String? + var boxModel: RadioBoxModel! open override var isSelected: Bool{ didSet{ - self.lineViewHeight?.constant = self.isSelected ? 4.0 : 0 - UIView.animate(withDuration: 0.5) { - self.layoutIfNeeded() + if let shapeLayer = self.bottomView.layer.sublayers?.filter({$0.name == "outofstock"}).first as? CAShapeLayer { + shapeLayer.strokeColor = isSelected ? UIColor.black.cgColor : UIColor.mfGet(forHex: "#747676").cgColor } + self.lineViewHeight?.constant = self.isSelected ? 4.0 : 0 self.bottomView.layer.sublayers?.filter({$0.name == "border"}).forEach({$0.removeFromSuperlayer()}) if(self.isSelected){ self.bottomView.layer.addBorder(edge: .bottom, color: UIColor.mfGet(forHex: "#0000"), thickness: 1.0) @@ -28,8 +30,11 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco self.bottomView.layer.addBorder(edge: .right, color: UIColor.mfGet(forHex: "#0000"), thickness: 1.0) } else { - self.addBordertoView() + self.addBordertoView("#747676") } + UIView.animate(withDuration: 0.5) { + self.layoutIfNeeded() + } } } @@ -77,7 +82,18 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco bottomView.addSubview(bodyLabel) NSLayoutConstraint.constraintPinSubview(bodyLabel, pinTop: false, topConstant:0 , pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: 12, pinRight: true, rightConstant: 12) bodyLabel.topAnchor.constraint(equalTo: lineView.bottomAnchor, constant: 12).isActive = true - bodyLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomView.bottomAnchor, constant: -12.0).isActive = true + + subTextLabel.numberOfLines = 1 + bottomView.addSubview(subTextLabel) + NSLayoutConstraint.constraintPinSubview(subTextLabel, pinTop: false, topConstant:0 , pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: 12, pinRight: true, rightConstant: 12) + subTextLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomView.bottomAnchor, constant: -12.0).isActive = true + subTextLabel.topAnchor.constraint(equalTo: bodyLabel.bottomAnchor, constant: 2).isActive = true + + subTextLabel.font = MFFonts.mfFontTXRegular(11.0) + bodyLabel.font = MFFonts.mfFontTXRegular(13.0) + subTextLabel.textColor = UIColor.mfGet(forHex: "#747676") + + } public func updateView(_ size: CGFloat) { @@ -85,15 +101,16 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco self.bottomView.setNeedsLayout() self.bottomView.layer.sublayers?.filter({$0.name == "border"}).forEach({$0.removeFromSuperlayer()}) DispatchQueue.main.async { [weak self] in - self?.addBordertoView() + guard let self = self else { return } + self.addBordertoView(self.boxModel.enabled ? "#747676" : "#D8DADA") } } - private func addBordertoView(){ - bottomView.layer.addBorder(edge: .bottom, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) - bottomView.layer.addBorder(edge: .left, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) - bottomView.layer.addBorder(edge: .right, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) - bottomView.layer.addBorder(edge: .top, color: UIColor.mfGet(forHex: "#747676"), thickness: 1.0) + private func addBordertoView(_ color:String){ + bottomView.layer.addBorder(edge: .bottom, color: UIColor.mfGet(forHex: color), thickness: 1.0) + bottomView.layer.addBorder(edge: .left, color: UIColor.mfGet(forHex: color), thickness: 1.0) + bottomView.layer.addBorder(edge: .right, color: UIColor.mfGet(forHex: color), thickness: 1.0) + bottomView.layer.addBorder(edge: .top, color: UIColor.mfGet(forHex: color), thickness: 1.0) } private func addOutOfStockLine(){ @@ -103,20 +120,22 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco let shapeLayer = CAShapeLayer() shapeLayer.name = "outofstock" shapeLayer.path = path.cgPath - shapeLayer.strokeColor = UIColor.darkGray.cgColor + shapeLayer.strokeColor = self.boxModel.enabled ? UIColor.black.cgColor : UIColor.mfGet(forHex: "#D8DADA").cgColor shapeLayer.lineWidth = 0.5 bottomView.layer.addSublayer(shapeLayer) } public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let collectionModel = model as? RadioBoxModel else { return } + boxModel = collectionModel if let backgroundColor = collectionModel.backgroundColor { bottomView.backgroundColor = backgroundColor.uiColor } self.isUserInteractionEnabled = collectionModel.enabled lineView.backgroundColor = collectionModel.selectedAccentColor?.uiColor bodyLabel.text = collectionModel.text - isSelected = collectionModel.selected + subTextLabel.text = collectionModel.subText +// isSelected = collectionModel.selected fieldValue = collectionModel.fieldValue isOutOfStock = collectionModel.strikethrough diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift index 31f58e53..4ce1e302 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift @@ -10,6 +10,7 @@ import Foundation @objcMembers public class RadioBoxModel: MoleculeModelProtocol { 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? = try? Color(colorString: "#D52B1E") public var selected: Bool = false @@ -20,6 +21,7 @@ import Foundation private enum CodingKeys: String, CodingKey { case moleculeName case text + case subText case selectedAccentColor case backgroundColor case selected @@ -31,6 +33,7 @@ import Foundation required public init(from decoder: Decoder) throws { 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 } @@ -52,6 +55,8 @@ import Foundation public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(text, forKey: .text) + try container.encodeIfPresent(subText, forKey: .subText) try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(selected, forKey: .selected) diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift index 90a0d684..ec0689bc 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift @@ -56,9 +56,15 @@ open class RadioBoxes: View { @objc override open func updateView(_ size: CGFloat) { collectionView.collectionViewLayout.invalidateLayout() DispatchQueue.main.async { [weak self] in - self?.setNeedsDisplay() - self?.collectionView.layoutIfNeeded() - self?.collectionView.reloadData() + guard let self = self else { return } + self.setNeedsDisplay() + self.collectionView.layoutIfNeeded() + self.collectionView.reloadData() + guard let firstSelectedIndex = self.boxes?.firstIndex(where: {$0.selected == true}) else { + return + } + self.collectionView.selectItem(at: IndexPath(item: firstSelectedIndex, section: 0), animated: true, scrollPosition: .centeredHorizontally) + } } From 7cba93e9f571672d462328cc06ead3e82caab0bd Mon Sep 17 00:00:00 2001 From: Damodaram <> Date: Thu, 9 Apr 2020 15:24:08 +0530 Subject: [PATCH 08/13] confluence changes Updated --- .../Views/RadioBoxCollectionViewCell.swift | 1 - .../Atomic/Atoms/Views/RadioBoxModel.swift | 11 ++++++++++ MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift | 22 +++++++++++++++---- .../Atomic/Atoms/Views/RadioBoxesModel.swift | 9 +------- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift index d959285d..419f278c 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift @@ -135,7 +135,6 @@ open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtoco lineView.backgroundColor = collectionModel.selectedAccentColor?.uiColor bodyLabel.text = collectionModel.text subTextLabel.text = collectionModel.subText -// isSelected = collectionModel.selected fieldValue = collectionModel.fieldValue isOutOfStock = collectionModel.strikethrough diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift index 4ce1e302..0c119ed8 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift @@ -17,6 +17,8 @@ import Foundation public var enabled: Bool = true public var strikethrough: Bool = false public var fieldValue: String? + public var fieldKey: String? + public var groupName: String? private enum CodingKeys: String, CodingKey { case moleculeName @@ -28,6 +30,9 @@ import Foundation case enabled case strikethrough case fieldValue + case fieldKey + case groupName + } required public init(from decoder: Decoder) throws { @@ -50,6 +55,9 @@ import Foundation strikethrough = isStrikeTrough } fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue) + fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) + groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) + } public func encode(to encoder: Encoder) throws { @@ -63,5 +71,8 @@ import Foundation try container.encodeIfPresent(enabled, forKey: .enabled) try container.encodeIfPresent(strikethrough, forKey: .strikethrough) try container.encodeIfPresent(fieldValue, forKey: .fieldValue) + try container.encodeIfPresent(fieldKey, forKey: .fieldKey) + try container.encodeIfPresent(groupName, forKey: .groupName) + } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift index ec0689bc..d0cae6b4 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift @@ -14,13 +14,18 @@ open class RadioBoxes: View { /// The models for the molecules. var boxes: [RadioBoxModel]? - public var fieldKey: String? - public var groupName: String? public var collectionViewHeight: NSLayoutConstraint? private let boxWidth: Double = 151.0 private let boxHeight: Double = 64.0 private let itemSpacing: Double = 10.0 private let leadingSpacing: Double = 0 + + public var selectedBox: RadioBoxModel? { + get{ + guard let selectedItem = collectionView.indexPathsForSelectedItems?.first else {return nil} + return boxes?[selectedItem.item] + } + } // MARK: - MVMCoreViewProtocol open override func setupView() { @@ -45,8 +50,6 @@ open class RadioBoxes: View { super.set(with: model, delegateObject, additionalData) guard let radioBoxesModel = model as? RadioBoxesModel else { return } backgroundColor = radioBoxesModel.backgroundColor?.uiColor - fieldKey = radioBoxesModel.fieldKey - groupName = radioBoxesModel.groupName registerCells() setupLayout(with: radioBoxesModel) prepareMolecules(with: radioBoxesModel) @@ -119,3 +122,14 @@ extension RadioBoxes: UICollectionViewDataSource { return cell } } +extension RadioBoxes: UICollectionViewDelegate { + public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + guard let boxItem = boxes?[indexPath.row] else { return } + boxItem.selected = true + } + public func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { + guard let boxItem = boxes?[indexPath.row] else { return } + boxItem.selected = false + } +} + diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift index 4e690ffa..d50978a1 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift @@ -12,16 +12,13 @@ import Foundation public var backgroundColor: Color? = Color(uiColor: .white) public var selectedAccentColor: Color? = Color(uiColor: .red) public var boxes: [RadioBoxModel] - public var fieldKey: String? - public var groupName: String? private enum CodingKeys: String, CodingKey { case moleculeName case selectedAccentColor case backgroundColor case boxes - case fieldKey - case groupName + } required public init(from decoder: Decoder) throws { @@ -33,8 +30,6 @@ import Foundation backgroundColor = color } boxes = try typeContainer.decode([RadioBoxModel].self, forKey: .boxes) - fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) - groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) } public func encode(to encoder: Encoder) throws { @@ -42,7 +37,5 @@ import Foundation try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) - try container.encodeIfPresent(fieldKey, forKey: .fieldKey) - try container.encodeIfPresent(groupName, forKey: .groupName) } } From 5ce98da559b77bf2b8c422b19f24a0eb7c5bf67d Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 10 Apr 2020 16:59:40 -0400 Subject: [PATCH 09/13] improvements --- MVMCoreUI.xcodeproj/project.pbxproj | 24 ++- MVMCoreUI/Atomic/Atoms/Views/RadioBox.swift | 159 +++++++++++++++++ .../Views/RadioBoxCollectionViewCell.swift | 165 +----------------- .../Atomic/Atoms/Views/RadioBoxModel.swift | 13 +- MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift | 11 +- .../Atomic/Atoms/Views/RadioBoxesModel.swift | 22 ++- MVMCoreUI/Atomic/Organisms/Carousel.swift | 4 - MVMCoreUI/BaseClasses/CollectionView.swift | 46 +++++ ...ProgrammaticCollectionViewController.swift | 7 +- 9 files changed, 255 insertions(+), 196 deletions(-) create mode 100644 MVMCoreUI/Atomic/Atoms/Views/RadioBox.swift create mode 100644 MVMCoreUI/BaseClasses/CollectionView.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 0cd70ea2..0af01831 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -202,7 +202,6 @@ BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6ABF242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift */; }; BB6C6AC824225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6AC62422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift */; }; BB6C6AC924225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6C6AC72422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift */; }; - BBAA4F02243D8E3B005AAD5F /* RadioBoxCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBAA4EFE243D8E3A005AAD5F /* RadioBoxCollectionViewCell.swift */; }; BBAA4F03243D8E3B005AAD5F /* RadioBoxes.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBAA4EFF243D8E3B005AAD5F /* RadioBoxes.swift */; }; BBAA4F04243D8E3B005AAD5F /* RadioBoxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBAA4F00243D8E3B005AAD5F /* RadioBoxModel.swift */; }; BBAA4F05243D8E3B005AAD5F /* RadioBoxesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBAA4F01243D8E3B005AAD5F /* RadioBoxesModel.swift */; }; @@ -268,6 +267,9 @@ D264FAA1243CF66B00D98315 /* ContainerCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAA0243CF66B00D98315 /* ContainerCollectionReusableView.swift */; }; D264FAA3243E632F00D98315 /* ProgrammaticCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAA2243E632F00D98315 /* ProgrammaticCollectionViewController.swift */; }; D264FAA5243F66A500D98315 /* CollectionTemplateItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAA4243F66A500D98315 /* CollectionTemplateItemProtocol.swift */; }; + D264FAA7243FE13B00D98315 /* RadioBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAA6243FE13B00D98315 /* RadioBox.swift */; }; + D264FAAA2440F97600D98315 /* CollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAA92440F97600D98315 /* CollectionView.swift */; }; + D264FAAC2441009400D98315 /* RadioBoxCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D264FAAB2441009400D98315 /* RadioBoxCollectionViewCell.swift */; }; D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368A23609801006832FA /* MoleculeStackItemModel.swift */; }; D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */; }; D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */; }; @@ -626,7 +628,6 @@ 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 = ""; }; BB6C6AC72422528F005F7224 /* ListOneColumnTextWithWhitespaceDividerShortModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOneColumnTextWithWhitespaceDividerShortModel.swift; sourceTree = ""; }; - BBAA4EFE243D8E3A005AAD5F /* RadioBoxCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxCollectionViewCell.swift; sourceTree = ""; }; BBAA4EFF243D8E3B005AAD5F /* RadioBoxes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxes.swift; sourceTree = ""; }; BBAA4F00243D8E3B005AAD5F /* RadioBoxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxModel.swift; sourceTree = ""; }; BBAA4F01243D8E3B005AAD5F /* RadioBoxesModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxesModel.swift; sourceTree = ""; }; @@ -692,6 +693,9 @@ D264FAA0243CF66B00D98315 /* ContainerCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerCollectionReusableView.swift; sourceTree = ""; }; D264FAA2243E632F00D98315 /* ProgrammaticCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgrammaticCollectionViewController.swift; sourceTree = ""; }; D264FAA4243F66A500D98315 /* CollectionTemplateItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionTemplateItemProtocol.swift; sourceTree = ""; }; + D264FAA6243FE13B00D98315 /* RadioBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBox.swift; sourceTree = ""; }; + D264FAA92440F97600D98315 /* CollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionView.swift; sourceTree = ""; }; + D264FAAB2441009400D98315 /* RadioBoxCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxCollectionViewCell.swift; sourceTree = ""; }; D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropDownFilterTableViewCell.swift; sourceTree = ""; }; D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemModel.swift; sourceTree = ""; }; D274CA322236A78900B01B62 /* FooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FooterView.swift; sourceTree = ""; }; @@ -1412,6 +1416,13 @@ path = Doughnut; sourceTree = ""; }; + D264FAA8243FE17A00D98315 /* Selectors */ = { + isa = PBXGroup; + children = ( + ); + path = Selectors; + sourceTree = ""; + }; D29DF0C221E404D4003B2FB9 = { isa = PBXGroup; children = ( @@ -1487,6 +1498,7 @@ D29DF10D21E67A70003B2FB9 /* Atoms */ = { isa = PBXGroup; children = ( + D264FAA8243FE17A00D98315 /* Selectors */, D29DF22B21E6A0FA003B2FB9 /* TextFields */, D29DF17D21E69E26003B2FB9 /* Views */, D29DF16821E69E1F003B2FB9 /* Buttons */, @@ -1639,10 +1651,11 @@ D29DF17D21E69E26003B2FB9 /* Views */ = { isa = PBXGroup; children = ( + D264FAAB2441009400D98315 /* RadioBoxCollectionViewCell.swift */, BBAA4F01243D8E3B005AAD5F /* RadioBoxesModel.swift */, BBAA4EFF243D8E3B005AAD5F /* RadioBoxes.swift */, BBAA4F00243D8E3B005AAD5F /* RadioBoxModel.swift */, - BBAA4EFE243D8E3A005AAD5F /* RadioBoxCollectionViewCell.swift */, + D264FAA6243FE13B00D98315 /* RadioBox.swift */, 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */, 01509D922327ECFB00EF99AA /* ProgressBar.swift */, 9445890D2385C3F800DE9FD4 /* MultiProgressModel.swift */, @@ -1835,6 +1848,7 @@ 0AE14F63238315D2005417F8 /* TextField.swift */, D2755D7A23689C7500485468 /* TableViewCell.swift */, D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */, + D264FAA92440F97600D98315 /* CollectionView.swift */, 0A5D59C323AD488600EFD9E9 /* Protocols */, ); path = BaseClasses; @@ -2044,6 +2058,7 @@ AA56A20F243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift in Sources */, 94C2D9A923872E5E0006CF46 /* LabelAttributeImageModel.swift in Sources */, DBC4391922442197001AB423 /* DashLine.swift in Sources */, + D264FAAA2440F97600D98315 /* CollectionView.swift in Sources */, 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */, D2FB151D23A40F1500C20E10 /* MoleculeStackItem.swift in Sources */, AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */, @@ -2122,7 +2137,6 @@ 525239C02407BCFF00454969 /* ListTwoColumnPriceDetailsModel.swift in Sources */, D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */, D202AFE6242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift in Sources */, - BBAA4F02243D8E3B005AAD5F /* RadioBoxCollectionViewCell.swift in Sources */, 8D084AD22410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift in Sources */, 94C0150C2421564A005811A9 /* ActionCollapseNotificationModel.swift in Sources */, 014AA73123C5059B006F3E93 /* ListPageTemplateModel.swift in Sources */, @@ -2232,6 +2246,7 @@ 526A265E240D200500B0D828 /* ListTwoColumnCompareChanges.swift in Sources */, 8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */, D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */, + D264FAAC2441009400D98315 /* RadioBoxCollectionViewCell.swift in Sources */, BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */, D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */, 012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */, @@ -2375,6 +2390,7 @@ D260106523D0CEA700764D80 /* StackModel.swift in Sources */, 0A6682AA2435125F00AD3CA1 /* Styler.swift in Sources */, D29770F521F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m in Sources */, + D264FAA7243FE13B00D98315 /* RadioBox.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBox.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBox.swift new file mode 100644 index 00000000..616c7fd6 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBox.swift @@ -0,0 +1,159 @@ +// +// RadioBox.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 4/9/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +open class RadioBox: Control { + public let label = Label.createLabelRegularBodySmall(true) + public let subTextLabel = Label.createLabelRegularMicro(true) + public var isOutOfStock = false + public var accentColor = UIColor.mvmRed + + public let innerPadding: CGFloat = 12.0 + + private var borderLayer: CALayer? + private var strikeLayer: CALayer? + private var maskLayer: CALayer? + + public var radioBoxModel: RadioBoxModel? { + return model as? RadioBoxModel + } + + open override func draw(_ layer: CALayer, in ctx: CGContext) { + // Draw the strikethrough + strikeLayer?.removeFromSuperlayer() + if isOutOfStock { + let line = getStrikeThrough(color: .black, thickness: 1) + layer.addSublayer(line) + strikeLayer = line + } + + // Draw the border + borderLayer?.removeFromSuperlayer() + if isSelected { + layer.borderWidth = 0 + let border = getSelectedBorder() + layer.addSublayer(border) + borderLayer = border + } else { + layer.borderWidth = 1 + } + + // Handle Mask + maskLayer?.removeFromSuperlayer() + if !isEnabled { + let mask = getMaskLayer() + layer.mask = mask + } + } + + open override func updateView(_ size: CGFloat) { + super.updateView(size) + label.updateView(size) + subTextLabel.updateView(size) + layer.setNeedsDisplay() + } + + open override func setupView() { + super.setupView() + + layer.delegate = self + layer.borderColor = UIColor.black.cgColor + layer.borderWidth = 1 + + label.numberOfLines = 1 + addSubview(label) + NSLayoutConstraint.constraintPinSubview(label, pinTop: true, topConstant: innerPadding, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: innerPadding, pinRight: true, rightConstant: innerPadding) + + subTextLabel.textColor = .mvmCoolGray6 + subTextLabel.numberOfLines = 1 + addSubview(subTextLabel) + NSLayoutConstraint.constraintPinSubview(subTextLabel, pinTop: false, topConstant:0, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: innerPadding, pinRight: true, rightConstant: innerPadding) + bottomAnchor.constraint(lessThanOrEqualTo: subTextLabel.bottomAnchor, constant: innerPadding).isActive = true + subTextLabel.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 2).isActive = true + + addTarget(self, action: #selector(touched), 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? RadioBoxModel else { return } + isSelected = model.selected + isEnabled = model.enabled + label.text = model.text + subTextLabel.text = model.subText + isOutOfStock = model.strikethrough + } + + @objc open func touched() { + isSelected = !isSelected + layer.setNeedsDisplay() + } + + /// Gets the selected state border + func getSelectedBorder() -> CAShapeLayer { + let layer = CAShapeLayer() + + let topLineWidth: CGFloat = 4 + let topLinePath = UIBezierPath() + topLinePath.lineWidth = topLineWidth + topLinePath.move(to: CGPoint(x: 0, y: topLineWidth / 2.0)) + topLinePath.addLine(to: CGPoint(x: bounds.width, y: topLineWidth / 2.0)) + + let topLineLayer = CAShapeLayer() + topLineLayer.fillColor = nil + topLineLayer.strokeColor = UIColor.mvmRed.cgColor + topLineLayer.lineWidth = 4 + topLineLayer.path = topLinePath.cgPath + layer.addSublayer(topLineLayer) + + let lineWidth: CGFloat = 1 + let halfLineWidth: CGFloat = 0.5 + let linePath = UIBezierPath() + linePath.move(to: CGPoint(x: halfLineWidth, y: topLineWidth)) + linePath.addLine(to: CGPoint(x: halfLineWidth, y: bounds.height)) + linePath.move(to: CGPoint(x: 0, y: bounds.height - halfLineWidth)) + linePath.addLine(to: CGPoint(x: bounds.width, y: bounds.height - halfLineWidth)) + linePath.move(to: CGPoint(x: bounds.width - halfLineWidth, y: bounds.height)) + linePath.addLine(to: CGPoint(x: bounds.width - halfLineWidth, y: topLineWidth)) + + let borderLayer = CAShapeLayer() + borderLayer.fillColor = nil + borderLayer.strokeColor = UIColor.black.cgColor + borderLayer.lineWidth = lineWidth + borderLayer.path = linePath.cgPath + layer.addSublayer(borderLayer) + + return layer + } + + /// Adds a border to edge + func getStrikeThrough(color: UIColor, thickness: CGFloat) -> CAShapeLayer { + let border = CAShapeLayer() + border.name = "strikethrough" + border.fillColor = nil + border.opacity = 1.0 + border.lineWidth = thickness + border.strokeColor = color.cgColor + + let linePath = UIBezierPath() + linePath.move(to: CGPoint(x: 0, y: bounds.height)) + linePath.addLine(to: CGPoint(x: bounds.width, y: 0)) + border.path = linePath.cgPath + return border + } + + 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/Views/RadioBoxCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift index 419f278c..c90b5e92 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift @@ -7,164 +7,17 @@ // import Foundation -open class RadioBoxCollectionViewCell: UICollectionViewCell, MoleculeViewProtocol { +open class RadioBoxCollectionViewCell: CollectionViewCell { + let radioBox = RadioBox() - public let bodyLabel = Label(frame: .zero) - public let subTextLabel = Label(frame: .zero) - public let lineView = View(frame: .zero) - var bottomView = MVMCoreUICommonViewsUtility.commonView() - public var lineViewHeight: NSLayoutConstraint? - public var fieldValue: String? - var boxModel: RadioBoxModel! - - open override var isSelected: Bool{ - didSet{ - if let shapeLayer = self.bottomView.layer.sublayers?.filter({$0.name == "outofstock"}).first as? CAShapeLayer { - shapeLayer.strokeColor = isSelected ? UIColor.black.cgColor : UIColor.mfGet(forHex: "#747676").cgColor - } - self.lineViewHeight?.constant = self.isSelected ? 4.0 : 0 - self.bottomView.layer.sublayers?.filter({$0.name == "border"}).forEach({$0.removeFromSuperlayer()}) - if(self.isSelected){ - self.bottomView.layer.addBorder(edge: .bottom, color: UIColor.mfGet(forHex: "#0000"), thickness: 1.0) - self.bottomView.layer.addBorder(edge: .left, color: UIColor.mfGet(forHex: "#0000"), thickness: 1.0) - self.bottomView.layer.addBorder(edge: .right, color: UIColor.mfGet(forHex: "#0000"), thickness: 1.0) - } - else { - self.addBordertoView("#747676") - } - UIView.animate(withDuration: 0.5) { - self.layoutIfNeeded() - } - } + open override func setupView() { + super.setupView() + addMolecule(radioBox) + MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0) } - var isOutOfStock: Bool = false { - didSet{ - DispatchQueue.main.async { [weak self] in - guard let self = self else { return } - self.bottomView.layer.sublayers?.filter({$0.name == "outofstock"}).forEach({$0.removeFromSuperlayer()}) - if(self.isOutOfStock) { - self.addOutOfStockLine() - } - } - } - } - - public override init(frame: CGRect) { - super.init(frame: .zero) - setupView() - } - - public required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - setupView() - } - - public func setupView() { - guard bottomView.superview == nil else { - return - } - isAccessibilityElement = false - contentView.isAccessibilityElement = false - insetsLayoutMarginsFromSafeArea = false - contentView.insetsLayoutMarginsFromSafeArea = false - contentView.preservesSuperviewLayoutMargins = false - bottomView.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(bottomView) - NSLayoutConstraint.constraintPinSubview(toSuperview: bottomView) - - bottomView.addSubview(lineView) - NSLayoutConstraint.constraintPinSubview(lineView, pinTop: true, pinBottom: false, pinLeft: true, pinRight: true) - lineViewHeight = lineView.heightAnchor.constraint(equalToConstant: 0) - lineViewHeight?.isActive = true - - bodyLabel.numberOfLines = 1 - bottomView.addSubview(bodyLabel) - NSLayoutConstraint.constraintPinSubview(bodyLabel, pinTop: false, topConstant:0 , pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: 12, pinRight: true, rightConstant: 12) - bodyLabel.topAnchor.constraint(equalTo: lineView.bottomAnchor, constant: 12).isActive = true - - subTextLabel.numberOfLines = 1 - bottomView.addSubview(subTextLabel) - NSLayoutConstraint.constraintPinSubview(subTextLabel, pinTop: false, topConstant:0 , pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: 12, pinRight: true, rightConstant: 12) - subTextLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomView.bottomAnchor, constant: -12.0).isActive = true - subTextLabel.topAnchor.constraint(equalTo: bodyLabel.bottomAnchor, constant: 2).isActive = true - - subTextLabel.font = MFFonts.mfFontTXRegular(11.0) - bodyLabel.font = MFFonts.mfFontTXRegular(13.0) - subTextLabel.textColor = UIColor.mfGet(forHex: "#747676") - - - } - - public func updateView(_ size: CGFloat) { - self.setNeedsLayout() - self.bottomView.setNeedsLayout() - self.bottomView.layer.sublayers?.filter({$0.name == "border"}).forEach({$0.removeFromSuperlayer()}) - DispatchQueue.main.async { [weak self] in - guard let self = self else { return } - self.addBordertoView(self.boxModel.enabled ? "#747676" : "#D8DADA") - } - } - - private func addBordertoView(_ color:String){ - bottomView.layer.addBorder(edge: .bottom, color: UIColor.mfGet(forHex: color), thickness: 1.0) - bottomView.layer.addBorder(edge: .left, color: UIColor.mfGet(forHex: color), thickness: 1.0) - bottomView.layer.addBorder(edge: .right, color: UIColor.mfGet(forHex: color), thickness: 1.0) - bottomView.layer.addBorder(edge: .top, color: UIColor.mfGet(forHex: color), thickness: 1.0) - } - - private func addOutOfStockLine(){ - let path = UIBezierPath() - path.move(to: CGPoint(x: 0, y: bottomView.bounds.height)) - path.addLine(to: CGPoint(x: bottomView.bounds.width, y: 0)) - let shapeLayer = CAShapeLayer() - shapeLayer.name = "outofstock" - shapeLayer.path = path.cgPath - shapeLayer.strokeColor = self.boxModel.enabled ? UIColor.black.cgColor : UIColor.mfGet(forHex: "#D8DADA").cgColor - shapeLayer.lineWidth = 0.5 - bottomView.layer.addSublayer(shapeLayer) - } - - public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - guard let collectionModel = model as? RadioBoxModel else { return } - boxModel = collectionModel - if let backgroundColor = collectionModel.backgroundColor { - bottomView.backgroundColor = backgroundColor.uiColor - } - self.isUserInteractionEnabled = collectionModel.enabled - lineView.backgroundColor = collectionModel.selectedAccentColor?.uiColor - bodyLabel.text = collectionModel.text - subTextLabel.text = collectionModel.subText - fieldValue = collectionModel.fieldValue - isOutOfStock = collectionModel.strikethrough - - } -} - -extension CALayer { - - func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) { - - let border = CALayer() - border.name = "border" - switch edge { - case UIRectEdge.top: - border.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: thickness) - break - case UIRectEdge.bottom: - border.frame = CGRect(x: 0, y: self.frame.height - thickness, width: self.frame.width, height: thickness) - break - case UIRectEdge.left: - border.frame = CGRect(x: 0, y: 0, width: thickness, height: self.frame.height) - break - case UIRectEdge.right: - border.frame = CGRect(x: self.frame.width - thickness, y: 0, width: thickness, height: self.frame.height) - break - default: - break - } - - border.backgroundColor = color.cgColor; - self.addSublayer(border) + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + guard let model = model as? RadioBoxModel else { return } + radioBox.set(with: model, delegateObject, additionalData) } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift index 0c119ed8..89bdc842 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift @@ -12,7 +12,7 @@ import Foundation public var text: String public var subText: String? public var backgroundColor: Color? = Color(uiColor: .white) - public var selectedAccentColor: Color? = try? Color(colorString: "#D52B1E") + public var selectedAccentColor = Color(uiColor: .mvmRed) public var selected: Bool = false public var enabled: Bool = true public var strikethrough: Bool = false @@ -32,7 +32,6 @@ import Foundation case fieldValue case fieldKey case groupName - } required public init(from decoder: Decoder) throws { @@ -57,7 +56,6 @@ import Foundation fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue) fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) - } public func encode(to encoder: Encoder) throws { @@ -65,14 +63,13 @@ import Foundation try container.encode(moleculeName, forKey: .moleculeName) try container.encode(text, forKey: .text) try container.encodeIfPresent(subText, forKey: .subText) - try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor) + try container.encode(selectedAccentColor, forKey: .selectedAccentColor) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) - try container.encodeIfPresent(selected, forKey: .selected) - try container.encodeIfPresent(enabled, forKey: .enabled) - try container.encodeIfPresent(strikethrough, forKey: .strikethrough) + try container.encode(selected, forKey: .selected) + try container.encode(enabled, forKey: .enabled) + try container.encode(strikethrough, forKey: .strikethrough) try container.encodeIfPresent(fieldValue, forKey: .fieldValue) try container.encodeIfPresent(fieldKey, forKey: .fieldKey) try container.encodeIfPresent(groupName, forKey: .groupName) - } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift index d0cae6b4..58090598 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift @@ -10,10 +10,10 @@ import Foundation open class RadioBoxes: View { - public let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + public let collectionView = CollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) /// The models for the molecules. - var boxes: [RadioBoxModel]? + public var boxes: [RadioBoxModel]? public var collectionViewHeight: NSLayoutConstraint? private let boxWidth: Double = 151.0 private let boxHeight: Double = 64.0 @@ -30,15 +30,8 @@ open class RadioBoxes: View { // MARK: - MVMCoreViewProtocol 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: 300) diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift index d50978a1..653eae13 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift @@ -9,33 +9,37 @@ import Foundation @objcMembers public class RadioBoxesModel: MoleculeModelProtocol { public static var identifier: String = "radioBoxes" - public var backgroundColor: Color? = Color(uiColor: .white) - public var selectedAccentColor: Color? = Color(uiColor: .red) + public var backgroundColor: Color? + public var selectedAccentColor: Color? public var boxes: [RadioBoxModel] + public var fieldKey: String? + public var groupName: String? private enum CodingKeys: String, CodingKey { case moleculeName case selectedAccentColor case backgroundColor case boxes - + case fieldKey + case groupName } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - 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) boxes = try typeContainer.decode([RadioBoxModel].self, forKey: .boxes) + fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) + groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(boxes, forKey: .boxes) try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(fieldKey, forKey: .fieldKey) + try container.encodeIfPresent(groupName, forKey: .groupName) } } diff --git a/MVMCoreUI/Atomic/Organisms/Carousel.swift b/MVMCoreUI/Atomic/Organisms/Carousel.swift index 1ed2ecd2..e900dda8 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel.swift @@ -83,12 +83,8 @@ open class Carousel: View { // MARK: - MVMCoreViewProtocol open override func setupView() { super.setupView() - collectionView.translatesAutoresizingMaskIntoConstraints = false collectionView.dataSource = self collectionView.delegate = self - collectionView.showsHorizontalScrollIndicator = false - collectionView.backgroundColor = .clear - collectionView.isAccessibilityElement = false addSubview(collectionView) bottomPin = NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView)?[ConstraintBot] as? NSLayoutConstraint diff --git a/MVMCoreUI/BaseClasses/CollectionView.swift b/MVMCoreUI/BaseClasses/CollectionView.swift new file mode 100644 index 00000000..ff572a2e --- /dev/null +++ b/MVMCoreUI/BaseClasses/CollectionView.swift @@ -0,0 +1,46 @@ +// +// CollectionView.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 4/10/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +open class CollectionView: UICollectionView, MVMCoreViewProtocol { + + private var initialSetupPerformed = false + + private func initialSetup() { + if !initialSetupPerformed { + initialSetupPerformed = true + setupView() + } + } + + public override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) { + super.init(frame: frame, collectionViewLayout: layout) + initialSetup() + } + + required public init?(coder: NSCoder) { + super.init(coder: coder) + initialSetup() + } + + public func updateView(_ size: CGFloat) { + for cell in visibleCells { + (cell as? MVMCoreViewProtocol)?.updateView(size) + } + collectionViewLayout.invalidateLayout() + } + + public func setupView() { + translatesAutoresizingMaskIntoConstraints = false + showsHorizontalScrollIndicator = false + backgroundColor = .clear + isAccessibilityElement = false + contentInsetAdjustmentBehavior = .always + } +} diff --git a/MVMCoreUI/BaseControllers/ProgrammaticCollectionViewController.swift b/MVMCoreUI/BaseControllers/ProgrammaticCollectionViewController.swift index 9d279d79..5e7b87b0 100644 --- a/MVMCoreUI/BaseControllers/ProgrammaticCollectionViewController.swift +++ b/MVMCoreUI/BaseControllers/ProgrammaticCollectionViewController.swift @@ -46,14 +46,9 @@ import Foundation /// Creates the collection view. open func createCollectionView() -> UICollectionView { - let collection = UICollectionView(frame: .zero, collectionViewLayout: createCollectionViewLayout()) - collection.translatesAutoresizingMaskIntoConstraints = false + let collection = CollectionView(frame: .zero, collectionViewLayout: createCollectionViewLayout()) collection.dataSource = self collection.delegate = self - collection.showsHorizontalScrollIndicator = false - collection.backgroundColor = .white - collection.isAccessibilityElement = false - collection.contentInsetAdjustmentBehavior = .always return collection } From b7b65e9d167ac7e4df587b3f8ba681b9363cb2f1 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 10 Apr 2020 20:25:57 -0400 Subject: [PATCH 10/13] Form Validation layout fixing --- MVMCoreUI/Atomic/Atoms/Views/RadioBox.swift | 94 +++++++----- .../Atomic/Atoms/Views/RadioBoxModel.swift | 19 ++- MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift | 135 ++++++++++-------- .../Atomic/Atoms/Views/RadioBoxesModel.swift | 20 ++- MVMCoreUI/Atomic/Organisms/Carousel.swift | 2 +- MVMCoreUI/BaseClasses/CollectionView.swift | 1 + 6 files changed, 166 insertions(+), 105 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBox.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBox.swift index 616c7fd6..da762dbb 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBox.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBox.swift @@ -20,10 +20,59 @@ open class RadioBox: Control { private var strikeLayer: CALayer? private var maskLayer: CALayer? + public var subTextLabelHeightConstraint: NSLayoutConstraint? + public var radioBoxModel: RadioBoxModel? { return model as? RadioBoxModel } + // MARK: - MVMCoreViewProtocol + + open override func updateView(_ size: CGFloat) { + super.updateView(size) + label.updateView(size) + subTextLabel.updateView(size) + layer.setNeedsDisplay() + } + + open override func setupView() { + super.setupView() + + layer.delegate = self + layer.borderColor = UIColor.black.cgColor + layer.borderWidth = 1 + + label.numberOfLines = 1 + addSubview(label) + NSLayoutConstraint.constraintPinSubview(label, pinTop: true, topConstant: innerPadding, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: innerPadding, pinRight: true, rightConstant: innerPadding) + + subTextLabel.textColor = .mvmCoolGray6 + subTextLabel.numberOfLines = 1 + addSubview(subTextLabel) + NSLayoutConstraint.constraintPinSubview(subTextLabel, pinTop: false, topConstant:0, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: innerPadding, pinRight: true, rightConstant: innerPadding) + bottomAnchor.constraint(greaterThanOrEqualTo: subTextLabel.bottomAnchor, constant: innerPadding).isActive = true + subTextLabel.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 2).isActive = true + subTextLabelHeightConstraint = subTextLabel.heightAnchor.constraint(equalToConstant: 0) + subTextLabelHeightConstraint?.isActive = true + + addTarget(self, action: #selector(selectBox), for: .touchUpInside) + } + + // MARK: - MoleculeViewProtocol + + public 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 + isEnabled = model.enabled + label.text = model.text + subTextLabel.text = model.subText + isOutOfStock = model.strikethrough + subTextLabelHeightConstraint?.isActive = (subTextLabel.text?.count ?? 0) == 0 + } + + // MARK: - State Handling + open override func draw(_ layer: CALayer, in ctx: CGContext) { // Draw the strikethrough strikeLayer?.removeFromSuperlayer() @@ -52,46 +101,21 @@ open class RadioBox: Control { } } - open override func updateView(_ size: CGFloat) { - super.updateView(size) - label.updateView(size) - subTextLabel.updateView(size) + open override func layoutSubviews() { + super.layoutSubviews() + // Accounts for any size changes layer.setNeedsDisplay() } - open override func setupView() { - super.setupView() - - layer.delegate = self - layer.borderColor = UIColor.black.cgColor - layer.borderWidth = 1 - - label.numberOfLines = 1 - addSubview(label) - NSLayoutConstraint.constraintPinSubview(label, pinTop: true, topConstant: innerPadding, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: innerPadding, pinRight: true, rightConstant: innerPadding) - - subTextLabel.textColor = .mvmCoolGray6 - subTextLabel.numberOfLines = 1 - addSubview(subTextLabel) - NSLayoutConstraint.constraintPinSubview(subTextLabel, pinTop: false, topConstant:0, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: innerPadding, pinRight: true, rightConstant: innerPadding) - bottomAnchor.constraint(lessThanOrEqualTo: subTextLabel.bottomAnchor, constant: innerPadding).isActive = true - subTextLabel.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 2).isActive = true - - addTarget(self, action: #selector(touched), for: .touchUpInside) + @objc open func selectBox() { + isSelected = true + radioBoxModel?.selected = isSelected + layer.setNeedsDisplay() } - public 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 - isEnabled = model.enabled - label.text = model.text - subTextLabel.text = model.subText - isOutOfStock = model.strikethrough - } - - @objc open func touched() { - isSelected = !isSelected + @objc open func deselectBox() { + isSelected = false + radioBoxModel?.selected = isSelected layer.setNeedsDisplay() } diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift index 89bdc842..caf26800 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift @@ -7,7 +7,7 @@ // import Foundation -@objcMembers public class RadioBoxModel: MoleculeModelProtocol { +@objcMembers public class RadioBoxModel: MoleculeModelProtocol, FormFieldProtocol { public static var identifier: String = "radioBox" public var text: String public var subText: String? @@ -18,8 +18,9 @@ import Foundation public var strikethrough: Bool = false public var fieldValue: String? public var fieldKey: String? - public var groupName: String? - + public var groupName: String = FormValidator.defaultGroupName + public var baseValue: AnyHashable? + private enum CodingKeys: String, CodingKey { case moleculeName case text @@ -34,6 +35,10 @@ import Foundation case groupName } + public func formFieldValue() -> AnyHashable? { + return selected + } + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) text = try typeContainer.decode(String.self, forKey: .text) @@ -53,9 +58,13 @@ import Foundation if let isStrikeTrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) { strikethrough = isStrikeTrough } + fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue) fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) - groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) + if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { + self.groupName = groupName + } + baseValue = selected } public func encode(to encoder: Encoder) throws { @@ -70,6 +79,6 @@ import Foundation try container.encode(strikethrough, forKey: .strikethrough) try container.encodeIfPresent(fieldValue, forKey: .fieldValue) try container.encodeIfPresent(fieldKey, forKey: .fieldKey) - try container.encodeIfPresent(groupName, forKey: .groupName) + try container.encode(groupName, forKey: .groupName) } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift index 58090598..6fe66bc2 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift @@ -10,28 +10,31 @@ import Foundation open class RadioBoxes: View { - public let collectionView = CollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + public var collectionView: CollectionView! + public var collectionViewHeight: NSLayoutConstraint! + private let boxWidth: CGFloat = 151.0 + private let boxHeight: CGFloat = 64.0 + private let itemSpacing: CGFloat = 8.0 + + private var delegateObject: MVMCoreUIDelegateObject? /// The models for the molecules. public var boxes: [RadioBoxModel]? - public var collectionViewHeight: NSLayoutConstraint? - private let boxWidth: Double = 151.0 - private let boxHeight: Double = 64.0 - private let itemSpacing: Double = 10.0 - private let leadingSpacing: Double = 0 - - public var selectedBox: RadioBoxModel? { - get{ - guard let selectedItem = collectionView.indexPathsForSelectedItems?.first else {return nil} - return boxes?[selectedItem.item] + + private var size: CGFloat? + + open override func layoutSubviews() { + super.layoutSubviews() + // Accounts for any collection size changes + DispatchQueue.main.async { + self.collectionView.collectionViewLayout.invalidateLayout() } } - + // MARK: - MVMCoreViewProtocol open override func setupView() { super.setupView() - collectionView.dataSource = self - collectionView.delegate = self + collectionView = createCollectionView() addSubview(collectionView) NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView) collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 300) @@ -41,62 +44,66 @@ open class RadioBoxes: View { // MARK: - MoleculeViewProtocol public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) + self.delegateObject = delegateObject + guard let radioBoxesModel = model as? RadioBoxesModel else { return } + boxes = radioBoxesModel.boxes + FormValidator.setupValidation(for: radioBoxesModel, delegate: delegateObject?.formHolderDelegate) + backgroundColor = radioBoxesModel.backgroundColor?.uiColor registerCells() - setupLayout(with: radioBoxesModel) - prepareMolecules(with: radioBoxesModel) + setHeight() collectionView.reloadData() } @objc override open func updateView(_ size: CGFloat) { - collectionView.collectionViewLayout.invalidateLayout() - DispatchQueue.main.async { [weak self] in - guard let self = self else { return } - self.setNeedsDisplay() - self.collectionView.layoutIfNeeded() - self.collectionView.reloadData() - guard let firstSelectedIndex = self.boxes?.firstIndex(where: {$0.selected == true}) else { - return - } - self.collectionView.selectItem(at: IndexPath(item: firstSelectedIndex, section: 0), animated: true, scrollPosition: .centeredHorizontally) - - } - } - - // MARK: - JSON Setters - /// Updates the layout being used - - func setupLayout(with radioBoxesModel: RadioBoxesModel?) { - let layout = UICollectionViewFlowLayout() - layout.scrollDirection = .vertical - layout.sectionInset = UIEdgeInsets.init(top: CGFloat(leadingSpacing), left: CGFloat(leadingSpacing), bottom: CGFloat(leadingSpacing), right: CGFloat(leadingSpacing)) - layout.minimumLineSpacing = 10 - layout.minimumInteritemSpacing = 10 - collectionView.collectionViewLayout = layout + super.updateView(size) + self.size = size + collectionView.updateView(size) } - func prepareMolecules(with radioBoxesModel: RadioBoxesModel?) { - guard let newMolecules = radioBoxesModel?.boxes else { - boxes = nil - return - } - boxes = newMolecules - let height = Double(round(Double((boxes?.count ?? Int(0.0)))/2.0))*(boxHeight+10.0) - collectionViewHeight?.constant = CGFloat(height) - collectionViewHeight?.isActive = true + // MARK: - Creation + + /// Creates the layout for the collection. + open func createCollectionViewLayout() -> UICollectionViewLayout { + let layout = UICollectionViewFlowLayout() + layout.scrollDirection = .vertical + layout.minimumLineSpacing = itemSpacing + layout.minimumInteritemSpacing = itemSpacing + return layout + } + + /// Creates the collection view. + open func createCollectionView() -> CollectionView { + let collection = CollectionView(frame: .zero, collectionViewLayout: createCollectionViewLayout()) + collection.dataSource = self + collection.delegate = self + return collection } /// Registers the cells with the collection view - func registerCells() { + open func registerCells() { collectionView.register(RadioBoxCollectionViewCell.self, forCellWithReuseIdentifier: "RadioBoxCollectionViewCell") } + + // MARK: - JSON Setters + open func setHeight() { + guard let boxes = boxes, boxes.count > 0 else { + collectionViewHeight.constant = 0 + return + } + + // Calculate the height + let rows = ceil(CGFloat(boxes.count) / 2.0) + let height = (rows * boxHeight) + ((rows - 1) * itemSpacing) + collectionViewHeight?.constant = height + } } extension RadioBoxes: UICollectionViewDelegateFlowLayout { open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { - let itemWidth = (Double(collectionView.bounds.width) - itemSpacing)/2 - return CGSize(width: CGFloat(itemWidth), height: CGFloat(boxHeight)) + let itemWidth: CGFloat = (collectionView.bounds.width - itemSpacing) / 2 + return CGSize(width: itemWidth, height: boxHeight) } } @@ -106,23 +113,31 @@ extension RadioBoxes: UICollectionViewDataSource { } open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - guard let molecule = boxes?[indexPath.row], let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioBoxCollectionViewCell", for: indexPath) as? RadioBoxCollectionViewCell else { - return UICollectionViewCell() + guard let molecule = boxes?[indexPath.row], + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioBoxCollectionViewCell", for: indexPath) as? RadioBoxCollectionViewCell else { + fatalError() + } + cell.radioBox.isUserInteractionEnabled = false + cell.set(with: molecule, delegateObject, nil) + cell.updateView(size ?? collectionView.bounds.width) + if molecule.selected { + collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically) } - cell.set(with: molecule, nil, nil) - cell.updateView(collectionView.bounds.width) cell.layoutIfNeeded() return cell } } + extension RadioBoxes: UICollectionViewDelegate { public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - guard let boxItem = boxes?[indexPath.row] else { return } - boxItem.selected = true + 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) { - guard let boxItem = boxes?[indexPath.row] else { return } - boxItem.selected = false + guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return } + cell.radioBox.deselectBox() } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift index 653eae13..28c4fab5 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift @@ -7,13 +7,22 @@ // import Foundation -@objcMembers public class RadioBoxesModel: MoleculeModelProtocol { +@objcMembers public class RadioBoxesModel: MoleculeModelProtocol, FormFieldProtocol { public static var identifier: String = "radioBoxes" public var backgroundColor: Color? public var selectedAccentColor: Color? public var boxes: [RadioBoxModel] public var fieldKey: String? - public var groupName: String? + public var groupName: String = FormValidator.defaultGroupName + public var baseValue: AnyHashable? + + /// Returns the fieldValue of the selected box, otherwise the text of the selected box. + public func formFieldValue() -> AnyHashable? { + let selectedBox = boxes.first { (box) -> Bool in + return box.selected + } + return selectedBox?.fieldValue ?? selectedBox?.text + } private enum CodingKeys: String, CodingKey { case moleculeName @@ -30,7 +39,10 @@ import Foundation backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) boxes = try typeContainer.decode([RadioBoxModel].self, forKey: .boxes) fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) - groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) + if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { + self.groupName = groupName + } + baseValue = formFieldValue() } public func encode(to encoder: Encoder) throws { @@ -40,6 +52,6 @@ import Foundation try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(fieldKey, forKey: .fieldKey) - try container.encodeIfPresent(groupName, forKey: .groupName) + try container.encode(groupName, forKey: .groupName) } } diff --git a/MVMCoreUI/Atomic/Organisms/Carousel.swift b/MVMCoreUI/Atomic/Organisms/Carousel.swift index e900dda8..820c5a5d 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel.swift @@ -10,7 +10,7 @@ import UIKit open class Carousel: View { - public let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + public let collectionView = CollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) /// The current index of the collection view. Includes dummy cells when looping. public var currentIndex = 0 diff --git a/MVMCoreUI/BaseClasses/CollectionView.swift b/MVMCoreUI/BaseClasses/CollectionView.swift index ff572a2e..a1a57376 100644 --- a/MVMCoreUI/BaseClasses/CollectionView.swift +++ b/MVMCoreUI/BaseClasses/CollectionView.swift @@ -39,6 +39,7 @@ open class CollectionView: UICollectionView, MVMCoreViewProtocol { public func setupView() { translatesAutoresizingMaskIntoConstraints = false showsHorizontalScrollIndicator = false + showsVerticalScrollIndicator = false backgroundColor = .clear isAccessibilityElement = false contentInsetAdjustmentBehavior = .always From e8b8d8132cc0447bcc066939e5ffded9d11d75d3 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 10 Apr 2020 20:32:12 -0400 Subject: [PATCH 11/13] remove form validator from radio box for now --- .../Atomic/Atoms/Views/RadioBoxModel.swift | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift index caf26800..b2a23c6a 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift @@ -7,7 +7,7 @@ // import Foundation -@objcMembers public class RadioBoxModel: MoleculeModelProtocol, FormFieldProtocol { +@objcMembers public class RadioBoxModel: MoleculeModelProtocol { public static var identifier: String = "radioBox" public var text: String public var subText: String? @@ -17,9 +17,6 @@ import Foundation public var enabled: Bool = true public var strikethrough: Bool = false public var fieldValue: String? - public var fieldKey: String? - public var groupName: String = FormValidator.defaultGroupName - public var baseValue: AnyHashable? private enum CodingKeys: String, CodingKey { case moleculeName @@ -31,12 +28,6 @@ import Foundation case enabled case strikethrough case fieldValue - case fieldKey - case groupName - } - - public func formFieldValue() -> AnyHashable? { - return selected } required public init(from decoder: Decoder) throws { @@ -60,11 +51,6 @@ import Foundation } fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue) - fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) - if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { - self.groupName = groupName - } - baseValue = selected } public func encode(to encoder: Encoder) throws { @@ -78,7 +64,5 @@ import Foundation try container.encode(enabled, forKey: .enabled) try container.encode(strikethrough, forKey: .strikethrough) try container.encodeIfPresent(fieldValue, forKey: .fieldValue) - try container.encodeIfPresent(fieldKey, forKey: .fieldKey) - try container.encode(groupName, forKey: .groupName) } } From c718cfa92af82796b1c1de273987f00eef3c1c00 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 10 Apr 2020 20:34:06 -0400 Subject: [PATCH 12/13] selectors folder --- MVMCoreUI.xcodeproj/project.pbxproj | 20 +++++++++---------- .../Atoms/{Views => Selectors}/Checkbox.swift | 0 .../{Views => Selectors}/CheckboxModel.swift | 0 .../Atoms/{Views => Selectors}/RadioBox.swift | 0 .../RadioBoxCollectionViewCell.swift | 0 .../{Views => Selectors}/RadioBoxModel.swift | 0 .../{Views => Selectors}/RadioBoxes.swift | 0 .../RadioBoxesModel.swift | 0 .../{Buttons => Selectors}/RadioButton.swift | 0 .../RadioButtonModel.swift | 0 .../RadioButtonSelectionHelper.swift | 0 11 files changed, 10 insertions(+), 10 deletions(-) rename MVMCoreUI/Atomic/Atoms/{Views => Selectors}/Checkbox.swift (100%) rename MVMCoreUI/Atomic/Atoms/{Views => Selectors}/CheckboxModel.swift (100%) rename MVMCoreUI/Atomic/Atoms/{Views => Selectors}/RadioBox.swift (100%) rename MVMCoreUI/Atomic/Atoms/{Views => Selectors}/RadioBoxCollectionViewCell.swift (100%) rename MVMCoreUI/Atomic/Atoms/{Views => Selectors}/RadioBoxModel.swift (100%) rename MVMCoreUI/Atomic/Atoms/{Views => Selectors}/RadioBoxes.swift (100%) rename MVMCoreUI/Atomic/Atoms/{Views => Selectors}/RadioBoxesModel.swift (100%) rename MVMCoreUI/Atomic/Atoms/{Buttons => Selectors}/RadioButton.swift (100%) rename MVMCoreUI/Atomic/Atoms/{Buttons => Selectors}/RadioButtonModel.swift (100%) rename MVMCoreUI/Atomic/Atoms/{Buttons => Selectors}/RadioButtonSelectionHelper.swift (100%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 0af01831..294f6188 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -1419,6 +1419,16 @@ D264FAA8243FE17A00D98315 /* Selectors */ = { isa = PBXGroup; children = ( + D264FAAB2441009400D98315 /* RadioBoxCollectionViewCell.swift */, + BBAA4F01243D8E3B005AAD5F /* RadioBoxesModel.swift */, + BBAA4EFF243D8E3B005AAD5F /* RadioBoxes.swift */, + BBAA4F00243D8E3B005AAD5F /* RadioBoxModel.swift */, + D264FAA6243FE13B00D98315 /* RadioBox.swift */, + 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */, + 011D95AE2407266E000E3791 /* RadioButtonModel.swift */, + 01004F2F22721C3800991ECC /* RadioButton.swift */, + 31BE15CA23D8924C00452370 /* CheckboxModel.swift */, + 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */, ); path = Selectors; sourceTree = ""; @@ -1641,9 +1651,6 @@ DBC4391A224421A0001AB423 /* CaretLink.swift */, D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */, D2E2A99E23E07F8A000B42E6 /* PillButton.swift */, - 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */, - 011D95AE2407266E000E3791 /* RadioButtonModel.swift */, - 01004F2F22721C3800991ECC /* RadioButton.swift */, ); path = Buttons; sourceTree = ""; @@ -1651,11 +1658,6 @@ D29DF17D21E69E26003B2FB9 /* Views */ = { isa = PBXGroup; children = ( - D264FAAB2441009400D98315 /* RadioBoxCollectionViewCell.swift */, - BBAA4F01243D8E3B005AAD5F /* RadioBoxesModel.swift */, - BBAA4EFF243D8E3B005AAD5F /* RadioBoxes.swift */, - BBAA4F00243D8E3B005AAD5F /* RadioBoxModel.swift */, - D264FAA6243FE13B00D98315 /* RadioBox.swift */, 9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */, 01509D922327ECFB00EF99AA /* ProgressBar.swift */, 9445890D2385C3F800DE9FD4 /* MultiProgressModel.swift */, @@ -1672,8 +1674,6 @@ 017BEB7A236763000024EF95 /* LineModel.swift */, D213347623843825008E41B3 /* Line.swift */, 94C2D9822386F3E30006CF46 /* Label */, - 31BE15CA23D8924C00452370 /* CheckboxModel.swift */, - 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */, 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */, 0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */, D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */, diff --git a/MVMCoreUI/Atomic/Atoms/Views/Checkbox.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Views/Checkbox.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift diff --git a/MVMCoreUI/Atomic/Atoms/Views/CheckboxModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Views/CheckboxModel.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBox.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Views/RadioBox.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioBox.swift diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxCollectionViewCell.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Views/RadioBoxCollectionViewCell.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxCollectionViewCell.swift diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Views/RadioBoxModel.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Views/RadioBoxes.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxes.swift diff --git a/MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Views/RadioBoxesModel.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/RadioButton.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioButton.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Buttons/RadioButton.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioButton.swift diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonModel.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonSelectionHelper.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonSelectionHelper.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonSelectionHelper.swift rename to MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonSelectionHelper.swift From cf5b554b851f23ea0e1572ca5838072ad1fdd216 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 10 Apr 2020 20:36:42 -0400 Subject: [PATCH 13/13] remove old comment no longer applicable --- MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 0f0baac6..ab0d5b43 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -47,7 +47,7 @@ import Foundation // need to move labelattributemodel to different method try? ModelRegistry.register(LabelAttributeFontModel.self) try? ModelRegistry.register(LabelAttributeColorModel.self) - try? ModelRegistry.register(LabelAttributeImageModel.self) // We need to separate the registry by types due to collisions... + try? ModelRegistry.register(LabelAttributeImageModel.self) try? ModelRegistry.register(LabelAttributeUnderlineModel.self) try? ModelRegistry.register(LabelAttributeStrikeThroughModel.self) try? ModelRegistry.register(LabelAttributeActionModel.self) @@ -66,9 +66,12 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ItemDropdownEntryField.self, viewModelClass: ItemDropdownEntryFieldModel.self) MoleculeObjectMapping.shared()?.register(viewClass: DateDropdownEntryField.self, viewModelClass: DateDropdownEntryFieldModel.self) - // Other Atoms + // Selectors + 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) + // Other Atoms MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self) MoleculeObjectMapping.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self) MoleculeObjectMapping.shared()?.register(viewClass: CaretView.self, viewModelClass: CaretViewModel.self) @@ -77,10 +80,8 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: Line.self, viewModelClass: LineModel.self) MoleculeObjectMapping.shared()?.register(viewClass: GraphView.self, viewModelClass: CircleProgressModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self) - MoleculeObjectMapping.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self) MoleculeObjectMapping.shared()?.register(viewClass: CheckboxLabel.self, viewModelClass: CheckboxLabelModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Arrow.self, viewModelClass: ArrowModel.self) - MoleculeObjectMapping.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self) MoleculeObjectMapping.shared()?.register(viewClass: RadioButtonLabel.self, viewModelClass: RadioButtonLabelModel.self) MoleculeObjectMapping.shared()?.register(viewClass: WebView.self, viewModelClass: WebViewModel.self)