diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index d7afb970..7b35fc55 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -266,6 +266,7 @@ D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */; }; D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; }; D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; }; + D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */; }; D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; }; D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260106423D0CEA700764D80 /* StackModel.swift */; }; D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9B245874F8002DE544 /* BGImageMolecule.swift */; }; @@ -680,6 +681,7 @@ D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescription.swift; sourceTree = ""; }; D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = ""; }; D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = ""; }; + D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItemProtocol.swift; sourceTree = ""; }; D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; D253BB9B245874F8002DE544 /* BGImageMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMolecule.swift; sourceTree = ""; }; D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMoleculeModel.swift; sourceTree = ""; }; @@ -850,6 +852,7 @@ children = ( D2E2A9A023E095AB000B42E6 /* ButtonModelProtocol.swift */, 014AA72323C501E2006F3E93 /* ContainerModelProtocol.swift */, + D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */, 012A88C3238D86E600FE3DA1 /* CarouselItemModelProtocol.swift */, 012A88B0238C880100FE3DA1 /* CarouselPagingModelProtocol.swift */, 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */, @@ -2226,6 +2229,7 @@ 013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */, 525239C22407BD1000454969 /* ListTwoColumnPriceDetails.swift in Sources */, D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */, + D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */, D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */, D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */, 94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Molecules/Items/CarouselItem.swift b/MVMCoreUI/Atomic/Molecules/Items/CarouselItem.swift index 3089596a..a37fe016 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/CarouselItem.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/CarouselItem.swift @@ -8,7 +8,7 @@ import Foundation -open class CarouselItem: MoleculeCollectionViewCell { +open class CarouselItem: MoleculeCollectionViewCell, CarouselItemProtocol { open var allowsPeaking = false var peakingLeftArrow = UIImageView(image: MVMCoreUIUtility.imageNamed("peakingRightArrow")?.withRenderingMode(.alwaysTemplate)) diff --git a/MVMCoreUI/Atomic/Organisms/Carousel.swift b/MVMCoreUI/Atomic/Organisms/Carousel.swift index 30d4c21e..9fa72b5d 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel.swift @@ -36,7 +36,7 @@ open class Carousel: View { open var numberOfPages = 0 /// The models for the molecules. - var molecules: [MoleculeModelProtocol]? + var molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]? /// The horizontal alignment of the cell in the collection view. Only noticeable if the itemWidthPercent is less than 100%. public var itemAlignment = UICollectionView.ScrollPosition.left @@ -176,11 +176,9 @@ open class Carousel: View { if carouselModel?.loop ?? false && newMolecules.count > 1 { // Sets up the row data with buffer cells on each side (for illusion of endless scroll... also has one more buffer cell on each side in case we can peek that cell). loop = true - - molecules?.insert(newMolecules.last!, at: 0) - molecules?.insert(newMolecules[(newMolecules.count - 2)], at: 0) - molecules?.append(newMolecules.first!) - molecules?.append(newMolecules[1]) + + molecules?.insert(contentsOf: newMolecules.suffix(2), at: 0) + molecules?.append(contentsOf: newMolecules.prefix(2)) } pageIndex = 0 @@ -259,15 +257,15 @@ open class Carousel: View { let visibleItemsPaths = collectionView.indexPathsForVisibleItems.sorted { $0.row < $1.row } if let firstItem = visibleItemsPaths.first, firstItem.row != currentIndex { - (collectionView.cellForItem(at: firstItem) as? CarouselItem)?.setPeaking(true, animated: true) + (collectionView.cellForItem(at: firstItem) as? CarouselItemProtocol)?.setPeaking(true, animated: true) } if let lastItem = visibleItemsPaths.last, lastItem.row != currentIndex { - (collectionView.cellForItem(at: lastItem) as? CarouselItem)?.setPeaking(true, animated: true) + (collectionView.cellForItem(at: lastItem) as? CarouselItemProtocol)?.setPeaking(true, animated: true) } } else { // Hide peaking. for item in collectionView.visibleCells { - (item as? CarouselItem)?.setPeaking(false, animated: true) + (item as? CarouselItemProtocol)?.setPeaking(false, animated: true) } } } @@ -301,7 +299,7 @@ extension Carousel: UICollectionViewDelegateFlowLayout { } open func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { - (cell as? CarouselItem)?.setPeaking(false, animated: false) + (cell as? CarouselItemProtocol)?.setPeaking(false, animated: false) } } diff --git a/MVMCoreUI/Atomic/Organisms/CarouselModel.swift b/MVMCoreUI/Atomic/Organisms/CarouselModel.swift index 857901e8..5ff753aa 100644 --- a/MVMCoreUI/Atomic/Organisms/CarouselModel.swift +++ b/MVMCoreUI/Atomic/Organisms/CarouselModel.swift @@ -19,7 +19,7 @@ import UIKit } public var backgroundColor: Color? - public var molecules: [CarouselItemModel] + public var molecules: [MoleculeModelProtocol & CarouselItemModelProtocol] public var index: Int = 0 public var spacing: Float? public var border: Bool? @@ -29,7 +29,7 @@ import UIKit public var itemAlignment: UICollectionView.ScrollPosition? public var pagingMolecule: (CarouselPagingModelProtocol & MoleculeModelProtocol)? - public init(molecules: [CarouselItemModel]) { + public init(molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]) { self.molecules = molecules } @@ -57,7 +57,7 @@ import UIKit required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - molecules = try typeContainer.decode([CarouselItemModel].self, forKey: .molecules) + molecules = try typeContainer.decodeModels(codingKey: .molecules) index = try typeContainer.decodeIfPresent(Int.self, forKey: .index) ?? 0 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) spacing = try typeContainer.decodeIfPresent(Float.self, forKey: .spacing) @@ -73,7 +73,7 @@ import UIKit var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) - try container.encode(molecules, forKey: .molecules) + try container.encodeModels(molecules, forKey: .molecules) try container.encode(spacing, forKey: .spacing) try container.encode(border, forKey: .border) try container.encode(loop, forKey: .loop) diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift index 093c9337..198cf80d 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift @@ -9,7 +9,5 @@ import Foundation -public protocol CarouselItemModelProtocol: ContainerModelProtocol, MoleculeModelProtocol { - var peakingUI: Bool? { get } - var peakingArrowColor: Color? { get } +public protocol CarouselItemModelProtocol: ContainerModelProtocol { } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemProtocol.swift new file mode 100644 index 00000000..4f49e5f7 --- /dev/null +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemProtocol.swift @@ -0,0 +1,15 @@ +// +// CarouselItemProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/20/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol CarouselItemProtocol: UICollectionViewCell { + + /// Notifies the cell if it is peaking or not. + func setPeaking(_ peaking: Bool, animated: Bool) +}