diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 331da73c..4fbd6e9d 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -213,12 +213,16 @@ AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C10724346F4B00151545 /* RadioSwatches.swift */; }; AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB9C109243496DD00151545 /* RadioSwatch.swift */; }; AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; }; + BB105859248DEFF70069D008 /* UICollectionViewLeftAlignedLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */; }; BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */; }; BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */; }; BB2BF0EA2452A9BB001D0FC2 /* ListDeviceComplexButtonSmall.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2BF0E92452A9BB001D0FC2 /* ListDeviceComplexButtonSmall.swift */; }; BB2BF0EC2452A9D5001D0FC2 /* ListDeviceComplexButtonSmallModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2BF0EB2452A9D5001D0FC2 /* ListDeviceComplexButtonSmallModel.swift */; }; BB2C968F24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */; }; BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */; }; + BB2FB3BB247E7EBC00DF73CD /* TagCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2FB3BA247E7EBC00DF73CD /* TagCollectionViewCell.swift */; }; + BB2FB3BD247E7EF200DF73CD /* Tags.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2FB3BC247E7EF200DF73CD /* Tags.swift */; }; + BB2FB3BF247E7F0900DF73CD /* TagsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2FB3BE247E7F0900DF73CD /* TagsModel.swift */; }; BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */; }; BB47A588241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */; }; BB54C5202434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */; }; @@ -234,6 +238,8 @@ 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 */; }; + BBC0C4FD24811DBC0087C44F /* Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC0C4FC24811DBC0087C44F /* Tag.swift */; }; + BBC0C4FF24811DCA0087C44F /* TagModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC0C4FE24811DCA0087C44F /* TagModel.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 */; }; @@ -650,12 +656,16 @@ AAB9C10724346F4B00151545 /* RadioSwatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatches.swift; sourceTree = ""; }; AAB9C109243496DD00151545 /* RadioSwatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatch.swift; sourceTree = ""; }; AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.swift; sourceTree = ""; }; + BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewLeftAlignedLayout.swift; sourceTree = ""; }; BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMediumModel.swift; sourceTree = ""; }; BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMedium.swift; sourceTree = ""; }; BB2BF0E92452A9BB001D0FC2 /* ListDeviceComplexButtonSmall.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonSmall.swift; sourceTree = ""; }; BB2BF0EB2452A9D5001D0FC2 /* ListDeviceComplexButtonSmallModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonSmallModel.swift; sourceTree = ""; }; BB2C968D24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinksModel.swift; sourceTree = ""; }; BB2C969124330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableTextLinkAllTextAndLinks.swift; sourceTree = ""; }; + BB2FB3BA247E7EBC00DF73CD /* TagCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagCollectionViewCell.swift; sourceTree = ""; }; + BB2FB3BC247E7EF200DF73CD /* Tags.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tags.swift; sourceTree = ""; }; + BB2FB3BE247E7F0900DF73CD /* TagsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagsModel.swift; sourceTree = ""; }; BB47A585241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsectionModel.swift; sourceTree = ""; }; BB47A587241615FA002BB23C /* ListOneColumnFullWidthTextDividerSubsection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextDividerSubsection.swift; sourceTree = ""; }; BB54C51E2434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListRightVariableButtonAllTextAndLinks.swift; sourceTree = ""; }; @@ -671,6 +681,8 @@ 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 = ""; }; + BBC0C4FC24811DBC0087C44F /* Tag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tag.swift; sourceTree = ""; }; + BBC0C4FE24811DCA0087C44F /* TagModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagModel.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 = ""; }; @@ -1543,8 +1555,8 @@ D29DF10D21E67A70003B2FB9 /* Atoms */ = { isa = PBXGroup; children = ( + D2BEFEF5248A954C00FAB3A9 /* FormFields */, D264FAA8243FE17A00D98315 /* Selectors */, - D29DF22B21E6A0FA003B2FB9 /* TextFields */, D29DF17D21E69E26003B2FB9 /* Views */, D29DF16821E69E1F003B2FB9 /* Buttons */, ); @@ -1856,6 +1868,7 @@ 0AE14F63238315D2005417F8 /* TextField.swift */, D20923582450ECE00044AD09 /* TableView.swift */, D2755D7A23689C7500485468 /* TableViewCell.swift */, + BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */, D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */, D264FAA92440F97600D98315 /* CollectionView.swift */, 0A5D59C323AD488600EFD9E9 /* Protocols */, @@ -1865,6 +1878,27 @@ path = BaseClasses; sourceTree = ""; }; + D2BEFEF5248A954C00FAB3A9 /* FormFields */ = { + isa = PBXGroup; + children = ( + D2BEFEF6248A957A00FAB3A9 /* Tags */, + D29DF22B21E6A0FA003B2FB9 /* TextFields */, + ); + path = FormFields; + sourceTree = ""; + }; + D2BEFEF6248A957A00FAB3A9 /* Tags */ = { + isa = PBXGroup; + children = ( + BBC0C4FE24811DCA0087C44F /* TagModel.swift */, + BBC0C4FC24811DBC0087C44F /* Tag.swift */, + BB2FB3BE247E7F0900DF73CD /* TagsModel.swift */, + BB2FB3BC247E7EF200DF73CD /* Tags.swift */, + BB2FB3BA247E7EBC00DF73CD /* TagCollectionViewCell.swift */, + ); + path = Tags; + sourceTree = ""; + }; D2C78CD324252F4E00B69FDE /* Atomic */ = { isa = PBXGroup; children = ( @@ -2033,6 +2067,7 @@ 94C2D9A923872E5E0006CF46 /* LabelAttributeImageModel.swift in Sources */, DBC4391922442197001AB423 /* DashLine.swift in Sources */, D264FAAA2440F97600D98315 /* CollectionView.swift in Sources */, + BBC0C4FF24811DCA0087C44F /* TagModel.swift in Sources */, 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */, D2FB151D23A40F1500C20E10 /* MoleculeStackItem.swift in Sources */, D28BA7452481652D00B75CB8 /* TabBarProtocol.swift in Sources */, @@ -2135,6 +2170,7 @@ D2755D7B23689C7500485468 /* TableViewCell.swift in Sources */, 0A25209624645AFD000FA9F6 /* TextViewEntryField.swift in Sources */, 014AA72623C501E2006F3E93 /* ContainerModelProtocol.swift in Sources */, + BB2FB3BF247E7F0900DF73CD /* TagsModel.swift in Sources */, AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */, 011D9626240EBB16000E3791 /* RadioButtonLabelModel.swift in Sources */, 8DDD6C1D244D90B8006A2232 /* ListThreeColumnDataUsage.swift in Sources */, @@ -2232,6 +2268,7 @@ 011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */, D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */, 8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */, + BBC0C4FD24811DBC0087C44F /* Tag.swift in Sources */, 94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */, 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */, @@ -2271,6 +2308,7 @@ D253BB9E2458751F002DE544 /* BGImageMoleculeModel.swift in Sources */, 0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */, 8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */, + BB2FB3BD247E7EF200DF73CD /* Tags.swift in Sources */, BBAA4F03243D8E3B005AAD5F /* RadioBoxes.swift in Sources */, D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */, 525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */, @@ -2291,6 +2329,7 @@ D2092355244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift in Sources */, 0AE14F64238315D2005417F8 /* TextField.swift in Sources */, 0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */, + BB105859248DEFF70069D008 /* UICollectionViewLeftAlignedLayout.swift in Sources */, D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */, D2C78CD224228BBD00B69FDE /* ActionOpenPanelModel.swift in Sources */, AA617AB02453010A00910B8F /* ListDeviceComplexLinkSmall.swift in Sources */, @@ -2316,6 +2355,7 @@ 0A21DB83235DFBC500C160A2 /* MdnEntryField.swift in Sources */, 0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */, D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */, + BB2FB3BB247E7EBC00DF73CD /* TagCollectionViewCell.swift in Sources */, 012A88C6238DA34000FE3DA1 /* ModuleMoleculeModel.swift in Sources */, 94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */, D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/Tag.swift b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/Tag.swift new file mode 100644 index 00000000..c962f8c9 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/Tag.swift @@ -0,0 +1,41 @@ +// +// Tag.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 29/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class Tag: View { + + public let label = Label.createLabelRegularBodySmall(true) + + // MARK: - MVMCoreViewProtocol + open override func setupView() { + super.setupView() + layer.borderColor = UIColor.mvmCoolGray6.cgColor + layer.borderWidth = 1 + label.numberOfLines = 1 + addSubview(label) + NSLayoutConstraint.constraintPinSubview(label, pinTop: true, topConstant: 13, pinBottom: true, bottomConstant: 13, pinLeft: true, leftConstant: 15, pinRight: true, rightConstant: 15) + } + + // MARK: - MoleculeViewProtocol + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + guard let model = model as? TagModel else { return } + label.set(with: model.label, delegateObject, additionalData) + } + + @objc override open func updateView(_ size: CGFloat) { + super.updateView(size) + label.updateView(size) + } + + open override func reset() { + super.reset() + label.reset() + label.styleRegularBodySmall(true) + } +} diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagCollectionViewCell.swift b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagCollectionViewCell.swift new file mode 100644 index 00000000..2b1406d5 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagCollectionViewCell.swift @@ -0,0 +1,29 @@ +// +// TagCollectionViewCell.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 27/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +open class TagCollectionViewCell: CollectionViewCell { + public let tagLabel = Tag() + + open override func reset() { + super.reset() + backgroundColor = .clear + } + + open override func setupView() { + super.setupView() + addMolecule(tagLabel) + MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0) + } + + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + guard let model = model as? TagModel else { return } + tagLabel.set(with: model, delegateObject, additionalData) + } +} diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift new file mode 100644 index 00000000..e0247e71 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift @@ -0,0 +1,37 @@ +// +// TagModel.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 29/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers public class TagModel: MoleculeModelProtocol { + public static var identifier: String = "tag" + public var label: LabelModel + public var action: ActionModelProtocol? + public var backgroundColor: Color? + + private enum CodingKeys: String, CodingKey { + case moleculeName + case label + case action + case backgroundColor + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + label = try typeContainer.decode(LabelModel.self, forKey: .label) + action = try typeContainer.decodeModelIfPresent(codingKey: .action) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(label, forKey: .label) + try container.encodeModelIfPresent(action, forKey: .action) + } +} diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/Tags.swift b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/Tags.swift new file mode 100644 index 00000000..4b1fa4f9 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/Tags.swift @@ -0,0 +1,105 @@ +// +// Tags.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 27/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +open class Tags: View, MFButtonProtocol { + public var collectionView: CollectionView! + public var collectionViewHeight: NSLayoutConstraint! + private var tagsListModel: TagsModel? { + return model as? TagsModel + } + + private var delegateObject: MVMCoreUIDelegateObject? + + /// The models for the molecules. + public var tags: [TagModel]? + + open override func layoutSubviews() { + super.layoutSubviews() + // Accounts for any collection size changes + DispatchQueue.main.async { + self.collectionView.collectionViewLayout.invalidateLayout() + self.collectionViewHeight.constant = self.collectionView.contentSize.height + self.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self) + } + } + + // MARK: - MVMCoreViewProtocol + open override func setupView() { + super.setupView() + collectionView = createCollectionView() + addSubview(collectionView) + NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView) + collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 300) + collectionViewHeight?.isActive = true + } + + // MARK: - MoleculeViewProtocol + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) + self.delegateObject = delegateObject + guard let tagsListModel = model as? TagsModel else { return } + tags = tagsListModel.tags + registerCells() + collectionView.reloadData() + } + + @objc override open func updateView(_ size: CGFloat) { + super.updateView(size) + collectionView.updateView(size) + } + + // MARK: - Creation + /// Creates the layout for the collection. + open func createCollectionViewLayout() -> UICollectionViewLayout { + let layout = UICollectionViewLeftAlignedLayout() + layout.estimatedItemSize = CGSize(width: 140, height: 40) + layout.minimumLineSpacing = 24.0 + layout.minimumInteritemSpacing = 12.0 + 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 + open func registerCells() { + collectionView.register(TagCollectionViewCell.self, forCellWithReuseIdentifier: "TagCollectionViewCell") + } +} + +extension Tags: UICollectionViewDataSource { + open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return tags?.count ?? 0 + } + + open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + guard let molecule = tags?[indexPath.row], + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TagCollectionViewCell", for: indexPath) as? TagCollectionViewCell else { + fatalError() + } + cell.reset() + cell.set(with: molecule, delegateObject, nil) + cell.layoutIfNeeded() + return cell + } +} + +extension Tags: UICollectionViewDelegate { + open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + guard let tagModel = tags?[indexPath.row], + let tagAction = tagModel.action else { return } + Button.performButtonAction(with: tagAction, button: self, delegateObject: delegateObject, additionalData: nil) + } +} diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift new file mode 100644 index 00000000..009f8fa1 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift @@ -0,0 +1,34 @@ +// +// TagsModel.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 27/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers public class TagsModel: MoleculeModelProtocol { + public static var identifier: String = "tags" + public var backgroundColor: Color? + public var tags: [TagModel] + + private enum CodingKeys: String, CodingKey { + case moleculeName + case backgroundColor + case tags + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + tags = try typeContainer.decode([TagModel].self, forKey: .tags) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(tags, forKey: .tags) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + } +} diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/BaseDropdownEntryField.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryField.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/BaseDropdownEntryField.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/BaseDropdownEntryFieldModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryFieldModel.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/BaseDropdownEntryFieldModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DateDropdownEntryField.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryField.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DateDropdownEntryField.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DateDropdownEntryFieldModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DateDropdownEntryFieldModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitBox.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitBox.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/DigitBox.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitBox.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitEntryField.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryField.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitEntryField.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitEntryFieldModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/DigitEntryFieldModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/EntryField.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryField.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryField.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryField.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryFieldModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/ItemDropdownEntryFieldModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/MdnEntryField.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryField.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/MdnEntryField.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/MdnEntryFieldModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryFieldModel.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/MdnEntryFieldModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryField.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryField.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryFieldModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryFieldModel.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextViewEntryField.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryField.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextViewEntryField.swift diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextViewEntryFieldModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Atoms/TextFields/TextViewEntryFieldModel.swift rename to MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextViewEntryFieldModel.swift diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 4f151642..bdccf353 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -85,6 +85,10 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: RadioBoxes.self, viewModelClass: RadioBoxesModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self) MoleculeObjectMapping.shared()?.register(viewClass: RadioSwatches.self, viewModelClass: RadioSwatchesModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: Tags.self, viewModelClass: TagsModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: Tag.self, viewModelClass: TagModel.self) + + // Other Atoms MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self) diff --git a/MVMCoreUI/BaseClasses/UICollectionViewLeftAlignedLayout.swift b/MVMCoreUI/BaseClasses/UICollectionViewLeftAlignedLayout.swift new file mode 100644 index 00000000..717bbc55 --- /dev/null +++ b/MVMCoreUI/BaseClasses/UICollectionViewLeftAlignedLayout.swift @@ -0,0 +1,27 @@ +// +// UICollectionViewLeftAlignedLayout.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 05/06/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// +// Left aligns items and makes the minimumInteritemSpacing absolute. + +import Foundation + +class UICollectionViewLeftAlignedLayout: UICollectionViewFlowLayout { + override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { + guard let attributes = super.layoutAttributesForElements(in: rect) else { return nil } + var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]() + for attribute in attributes { + if let previousFrame = newAttributesForElementsInRect.last, + MVMCoreGetterUtility.cgfequal(previousFrame.frame.minY, attribute.frame.minY) { + attribute.frame.origin.x = previousFrame.frame.maxX + minimumInteritemSpacing + } else { + attribute.frame.origin.x = 0 + } + newAttributesForElementsInRect.append(attribute) + } + return newAttributesForElementsInRect + } +}