diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 8b6e581a..98d19f8a 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -215,6 +215,7 @@ AAC6F167243332E400F295C1 /* RadioSwatchesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */; }; BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */; }; BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */; }; + BB258D37248A259000125E9D /* UICollectionViewLeftAlignedLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB258D36248A259000125E9D /* UICollectionViewLeftAlignedLayout.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 */; }; @@ -222,7 +223,6 @@ BB2FB3BB247E7EBC00DF73CD /* TagCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2FB3BA247E7EBC00DF73CD /* TagCollectionViewCell.swift */; }; BB2FB3BD247E7EF200DF73CD /* TagsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2FB3BC247E7EF200DF73CD /* TagsList.swift */; }; BB2FB3BF247E7F0900DF73CD /* TagsListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2FB3BE247E7F0900DF73CD /* TagsListModel.swift */; }; - BB2FB3C1247EC1EB00DF73CD /* CustomCollectionViewFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2FB3C0247EC1EB00DF73CD /* CustomCollectionViewFlowLayout.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 */; }; @@ -654,6 +654,7 @@ AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchesModel.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 = ""; }; + BB258D36248A259000125E9D /* UICollectionViewLeftAlignedLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UICollectionViewLeftAlignedLayout.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 = ""; }; @@ -661,7 +662,6 @@ BB2FB3BA247E7EBC00DF73CD /* TagCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagCollectionViewCell.swift; sourceTree = ""; }; BB2FB3BC247E7EF200DF73CD /* TagsList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagsList.swift; sourceTree = ""; }; BB2FB3BE247E7F0900DF73CD /* TagsListModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagsListModel.swift; sourceTree = ""; }; - BB2FB3C0247EC1EB00DF73CD /* CustomCollectionViewFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomCollectionViewFlowLayout.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 = ""; }; @@ -1445,12 +1445,12 @@ D264FAA8243FE17A00D98315 /* Selectors */ = { isa = PBXGroup; children = ( + BB2FB3BE247E7F0900DF73CD /* TagsListModel.swift */, + BB2FB3BC247E7EF200DF73CD /* TagsList.swift */, + BB258D36248A259000125E9D /* UICollectionViewLeftAlignedLayout.swift */, BBC0C4FE24811DCA0087C44F /* TagModel.swift */, BBC0C4FC24811DBC0087C44F /* Tag.swift */, BB2FB3BA247E7EBC00DF73CD /* TagCollectionViewCell.swift */, - BB2FB3C0247EC1EB00DF73CD /* CustomCollectionViewFlowLayout.swift */, - BB2FB3BC247E7EF200DF73CD /* TagsList.swift */, - BB2FB3BE247E7F0900DF73CD /* TagsListModel.swift */, D264FAAB2441009400D98315 /* RadioBoxCollectionViewCell.swift */, BBAA4F01243D8E3B005AAD5F /* RadioBoxesModel.swift */, BBAA4EFF243D8E3B005AAD5F /* RadioBoxes.swift */, @@ -2205,7 +2205,6 @@ D260105D23D0BCD400764D80 /* Stack.swift in Sources */, 0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */, BB54C5212434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift in Sources */, - BB2FB3C1247EC1EB00DF73CD /* CustomCollectionViewFlowLayout.swift in Sources */, D2092349244A51D40044AD09 /* RadioSwatchModel.swift in Sources */, 8DD1E370243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift in Sources */, D23EA802247EBED400D60C34 /* ImageBarButtonItem.swift in Sources */, @@ -2298,6 +2297,7 @@ 012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */, D2092355244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift in Sources */, 0AE14F64238315D2005417F8 /* TextField.swift in Sources */, + BB258D37248A259000125E9D /* UICollectionViewLeftAlignedLayout.swift in Sources */, 0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */, D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */, D2C78CD224228BBD00B69FDE /* ActionOpenPanelModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/CustomCollectionViewFlowLayout.swift b/MVMCoreUI/Atomic/Atoms/Selectors/CustomCollectionViewFlowLayout.swift deleted file mode 100644 index aadad8b9..00000000 --- a/MVMCoreUI/Atomic/Atoms/Selectors/CustomCollectionViewFlowLayout.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// CollectionViewCenterLayout.swift -// MVMCoreUI -// -// Created by Dhamodaram Nandi on 27/05/20. -// Copyright © 2020 Verizon Wireless. All rights reserved. -// - -import UIKit - - -class UICollectionViewCenterLayout: UICollectionViewFlowLayout { - - override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { - let attributesForElementsInRect = super.layoutAttributesForElements(in: rect) - var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]() - - var leftMargin: CGFloat = 0.0; - - for attributes in attributesForElementsInRect! { - if (attributes.frame.origin.x == self.sectionInset.left) { - leftMargin = self.sectionInset.left - } else { - var newLeftAlignedFrame = attributes.frame - newLeftAlignedFrame.origin.x = leftMargin - attributes.frame = newLeftAlignedFrame - } - leftMargin += attributes.frame.size.width + 8 - newAttributesForElementsInRect.append(attributes) - } - - return newAttributesForElementsInRect - } -} diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/Tag.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Tag.swift index cd66ff12..92624647 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/Tag.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/Tag.swift @@ -19,7 +19,6 @@ import Foundation 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 @@ -30,6 +29,6 @@ import Foundation @objc override open func updateView(_ size: CGFloat) { super.updateView(size) + label.updateView(size) } - } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/TagModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/TagModel.swift index a6ee8685..3ab66b0d 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/TagModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/TagModel.swift @@ -18,13 +18,13 @@ import Foundation 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) + action = try typeContainer.decodeModelIfPresent(codingKey: .action) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) } public func encode(to encoder: Encoder) throws { @@ -32,6 +32,5 @@ import Foundation try container.encode(moleculeName, forKey: .moleculeName) try container.encode(label, forKey: .label) try container.encodeModelIfPresent(action, forKey: .action) - } } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/TagsList.swift b/MVMCoreUI/Atomic/Atoms/Selectors/TagsList.swift index f79d4290..bd3603dd 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/TagsList.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/TagsList.swift @@ -11,7 +11,6 @@ open class TagsList: View { public var collectionView: CollectionView! public var collectionViewHeight: NSLayoutConstraint! - private let itemSpacing: CGFloat = 12.0 private var tagsListModel: TagsListModel? { return model as? TagsListModel } @@ -27,6 +26,9 @@ open class TagsList: View { // Accounts for any collection size changes DispatchQueue.main.async { self.collectionView.collectionViewLayout.invalidateLayout() + self.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self) + self.collectionViewHeight.constant = self.collectionView.contentSize.height + self.collectionViewHeight.isActive = true } } @@ -36,7 +38,7 @@ open class TagsList: View { collectionView = createCollectionView() addSubview(collectionView) NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView) - collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 200) + collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 300) collectionViewHeight?.isActive = true } @@ -49,10 +51,6 @@ open class TagsList: View { tags = tagsListModel.tags registerCells() collectionView.reloadData() - if let height = tagsListModel.height { - collectionViewHeight?.constant = CGFloat(height) - collectionViewHeight?.isActive = true - } } @objc override open func updateView(_ size: CGFloat) { @@ -64,11 +62,10 @@ open class TagsList: View { /// Creates the layout for the collection. open func createCollectionViewLayout() -> UICollectionViewLayout { - let layout = UICollectionViewCenterLayout() + let layout = UICollectionViewLeftAlignedLayout() layout.scrollDirection = .vertical layout.estimatedItemSize = CGSize(width: 140, height: 40) layout.minimumLineSpacing = 24.0 - layout.minimumInteritemSpacing = itemSpacing return layout } @@ -108,6 +105,7 @@ extension TagsList: UICollectionViewDelegate { open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { guard let tagModel = tags?[indexPath.row] else {return} + Button. if let data = try? tagModel.action?.encode(using: JSONEncoder()), let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any]{ MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: nil, delegateObject: delegateObject) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/TagsListModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/TagsListModel.swift index ff24c236..75d7c4e9 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/TagsListModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/TagsListModel.swift @@ -13,8 +13,7 @@ import Foundation public var backgroundColor: Color? public static var identifier: String = "tagsList" public var tags: [TagModel] - public var height: Float? - + private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor @@ -26,7 +25,6 @@ import Foundation let typeContainer = try decoder.container(keyedBy: CodingKeys.self) tags = try typeContainer.decode([TagModel].self, forKey: .tags) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - height = try typeContainer.decodeIfPresent(Float.self, forKey: .height) } public func encode(to encoder: Encoder) throws { @@ -34,6 +32,5 @@ import Foundation try container.encode(moleculeName, forKey: .moleculeName) try container.encode(tags, forKey: .tags) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) - try container.encode(height, forKey: .height) } } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/UICollectionViewLeftAlignedLayout.swift b/MVMCoreUI/Atomic/Atoms/Selectors/UICollectionViewLeftAlignedLayout.swift new file mode 100644 index 00000000..96dc3a63 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Selectors/UICollectionViewLeftAlignedLayout.swift @@ -0,0 +1,53 @@ +// +// UICollectionViewLeftAlignedLayout.swift +// MVMCoreUI +// +// Created by Dhamodaram Nandi on 05/06/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +class UICollectionViewLeftAlignedLayout: UICollectionViewFlowLayout { + override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { + guard let attributes = super.layoutAttributesForElements(in: rect) else { + return nil + } + + var rows = [Row]() + var currentRowY: CGFloat = -1 + + for attribute in attributes { + if currentRowY != attribute.frame.origin.y { + currentRowY = attribute.frame.origin.y + rows.append(Row(spacing: 10)) + } + rows.last?.add(attribute: attribute) + } + + rows.forEach { $0.tagLayout(collectionViewWidth: collectionView?.frame.width ?? 0) } + return rows.flatMap { $0.attributes } + } +} +class Row { + + var attributes = [UICollectionViewLayoutAttributes]() + var spacing: CGFloat = 0 + + init(spacing: CGFloat) { + self.spacing = spacing + } + + func add(attribute: UICollectionViewLayoutAttributes) { + attributes.append(attribute) + } + + func tagLayout(collectionViewWidth: CGFloat) { + let padding = 8 + var offset = padding + for attribute in attributes { + attribute.frame.origin.x = CGFloat(offset) + offset += Int(attribute.frame.width + spacing) + } + } +}