diff --git a/MVMCoreUI/Atoms/Views/CarouselIndicator/CarouselIndicator.swift b/MVMCoreUI/Atoms/Views/CarouselIndicator/CarouselIndicator.swift index f374fafe..5b1269fd 100644 --- a/MVMCoreUI/Atoms/Views/CarouselIndicator/CarouselIndicator.swift +++ b/MVMCoreUI/Atoms/Views/CarouselIndicator/CarouselIndicator.swift @@ -36,7 +36,7 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { /// The types of indicators that can appear. public enum IndicatorType: String { - case bar + case bars case numeric case hybrid // bar & numeric } @@ -77,29 +77,10 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { } } - /// The maxmum count of pages before the indicatorView forces a Numeric Indicator in place of Bar. - public var hybridThreshold: Int = 5 - /// Set this closure to perform an action when a different indicator was selected. /// Passes through oldInde and newIndex, respectively. public var indicatorTouchAction: ((CarouselPageControlProtocol) -> ())? - - /// Allows sendActions() to trigger even if index is already at min/max index. - public var alwaysSendAction = false - - /// Set true to make the accessibility value as "Slide #currentPage of #totalPage", otherwise will be "Page #currentPage of #totalPage", default is false - public var accessibilityHasSlidesInsteadOfPage = false - - public var isAnimated = true - - /// Will hide this control if page count is 1. - public var hidesForSinglePage = false { - didSet { isHidden = hidesForSinglePage && numberOfPages <= 1 } - } - - /// If true, then index will wraparound, otherwise it will stop paging at min/max index. - public var allowIndexWraparound = false - + public override var isEnabled: Bool { didSet { isUserInteractionEnabled = isEnabled @@ -117,10 +98,7 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { public var currentIndex: Int { get { return _currentIndex } set (newIndex) { - if !allowIndexWraparound { - guard _currentIndex != newIndex else { return } - } - + previousIndex = _currentIndex _currentIndex = newIndex performAction() @@ -138,7 +116,7 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { guard _numberOfPages != newTotal else { return } _numberOfPages = newTotal - isHidden = hidesForSinglePage && newTotal <= 1 + isHidden = carouselIndicatorModel?.hidesForSinglePage ?? false && newTotal <= 1 if isBarIndicator() { (indicatorView as? BarsIndicatorView)?.generateBars() @@ -148,14 +126,14 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { } } - public var disabledIndicatorColor: UIColor = .mvmCoolGray3 - - private var _indicatorTintColor: UIColor = .black + public var disabledIndicatorColor: UIColor { + return carouselIndicatorModel?.disabledIndicatorColor.uiColor ?? .mvmCoolGray3 + } public var indicatorTintColor: UIColor { - get { return _indicatorTintColor } + get { return carouselIndicatorModel?.indicatorColor.uiColor ?? .black } set (newColor) { - _indicatorTintColor = newColor + carouselIndicatorModel?.indicatorColor = Color(uiColor: newColor) if isBarIndicator(), let barIndicator = indicatorView as? BarsIndicatorView { for (i, barTuple) in barIndicator.barReferences.enumerated() where i != currentIndex { @@ -175,7 +153,7 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { carouselIndicatorModel?.currentIndicatorColor = Color(uiColor: newColor) if isBarIndicator() { - if let barIndicator = indicatorView as? BarsIndicatorView { + if let barIndicator = indicatorView as? BarsIndicatorView, !barIndicator.barReferences.isEmpty { barIndicator.barReferences[currentIndex].view.backgroundColor = newColor } } @@ -219,10 +197,6 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { assignIndicatorView() setupGestures() - - if let accessibleValue = MVMCoreUIUtility.hardcodedString(withKey: accessibilityHasSlidesInsteadOfPage ? "MVMCoreUIPageControlslides_currentpage_index" : "MVMCoreUIPageControl_currentpage_index") { - accessibilityValue = String(format: accessibleValue, currentIndex + 1, numberOfPages) - } } //-------------------------------------------------- @@ -293,7 +267,7 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { indicatorView?.updateUI(previousIndex: previousIndex, newIndex: currentIndex, totalCount: numberOfPages, - isAnimated: isAnimated) + isAnimated: carouselIndicatorModel?.isAnimated ?? true) } public func performAction() { @@ -306,20 +280,21 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { func assignIndicatorView() { switch indicatorType { - case .bar: + case .bars: indicatorView = BarsIndicatorView() case .numeric: indicatorView = NumericIndicatorView() case .hybrid: - indicatorView = numberOfPages >= hybridThreshold ? NumericIndicatorView() : BarsIndicatorView() + + indicatorView = numberOfPages >= carouselIndicatorModel?.hybridThreshold ?? 0 ? NumericIndicatorView() : BarsIndicatorView() } } /// Convenience to determine if current view is displaying bars. func isBarIndicator() -> Bool { - return indicatorType == .bar || indicatorType == .hybrid && numberOfPages <= hybridThreshold + return indicatorType == .bars || indicatorType == .hybrid && numberOfPages <= carouselIndicatorModel?.hybridThreshold ?? 5 } public func scrollViewDidScroll(_ collectionView: UICollectionView) { } @@ -328,18 +303,20 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { // MARK: - MoleculeViewProtocol //-------------------------------------------------- - - open override func set(with model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { -// super.setWithModel(model, delegateObject, additionalData) + // super.setWithModel(model, delegateObject, additionalData) guard let model = model as? CarouselIndicatorModel else { return } - indicatorType = IndicatorType(rawValue: model.type ?? "") ?? .hybrid + indicatorType = IndicatorType(rawValue: model.type) ?? .hybrid backgroundColor = model.backgroundColor?.uiColor - // barsColor = model.barsColor - // pageIndicatorTintColor - // currentPageIndicatorTintColor + currentIndicatorColor = model.currentIndicatorColor.uiColor + indicatorTintColor = model.indicatorColor.uiColor + isEnabled = model.isEnabled + + if let accessibleValue = MVMCoreUIUtility.hardcodedString(withKey: model.accessibilityHasSlidesInsteadOfPage ? "MVMCoreUIPageControlslides_currentpage_index" : "MVMCoreUIPageControl_currentpage_index") { + accessibilityValue = String(format: accessibleValue, currentIndex + 1, numberOfPages) + } } //-------------------------------------------------- @@ -358,8 +335,8 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { func accessibilityAdjust(toPage index: Int) { - if (index < numberOfPages && index >= 0) || alwaysSendAction { - isAnimated = false + if (index < numberOfPages && index >= 0) || carouselIndicatorModel?.alwaysSendAction ?? false { + carouselIndicatorModel?.isAnimated = false previousIndex = currentIndex currentIndex = index performAction() diff --git a/MVMCoreUI/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift b/MVMCoreUI/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift index 2e9c6c77..051f25ec 100644 --- a/MVMCoreUI/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift +++ b/MVMCoreUI/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift @@ -21,20 +21,22 @@ public class CarouselIndicatorModel: CarouselPagingModelProtocol { public var backgroundColor: Color? public var moleculeName: String? public var type: String = "hybrid" + + /// The maxmum count of pages before the indicatorView forces a Numeric Indicator in place of Bar. public var hybridThreshold: Int = 5 - public var barsColor: Color? - public var currentBarColor: Color? - public var currentIndex: Int = 0 public var numberOfPages: Int = 0 - public var alwaysSendEvent: Bool = false public var isAnimated: Bool = true public var hidesForSinglePage: Bool = false + /// Set true to make the accessibility value as "Slide #currentPage of #totalPage", otherwise will be "Page #currentPage of #totalPage", default is false public var accessibilityHasSlidesInsteadOfPage: Bool = false - public var isEnabled: Bool = false + public var isEnabled: Bool = true public var disabledIndicatorColor: Color = Color(uiColor: .mvmCoolGray3) - public var indicatorTintColor: Color = Color(uiColor: .mvmBlack) + public var indicatorColor: Color = Color(uiColor: .mvmBlack) public var currentIndicatorColor: Color = Color(uiColor: .mvmBlack) - public var position: Float? + public var padding: Float? + + /// Allows sendActions() to trigger even if index is already at min/max index. + public var alwaysSendAction = false //-------------------------------------------------- // MARK: - Keys @@ -45,18 +47,16 @@ public class CarouselIndicatorModel: CarouselPagingModelProtocol { case backgroundColor case type case hybridThreshold - case barsColor - case currentBarColor - case currentIndex case numberOfPages - case alwaysSendEvent + case alwaysSendAction case isAnimated case hidesForSinglePage case accessibilityHasSlidesInsteadOfPage case isEnabled case disabledIndicatorColor - case indicatorTintColor + case indicatorColor case currentIndicatorColor + case padding } //-------------------------------------------------- @@ -66,12 +66,8 @@ public class CarouselIndicatorModel: CarouselPagingModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName) - currentBarColor = try typeContainer.decodeIfPresent(Color.self, forKey: .currentBarColor) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - barsColor = try typeContainer.decodeIfPresent(Color.self, forKey: .barsColor) - barsColor = try typeContainer.decodeIfPresent(Color.self, forKey: .barsColor) - currentBarColor = try typeContainer.decodeIfPresent(Color.self, forKey: .currentBarColor) - + if let type = try typeContainer.decodeIfPresent(String.self, forKey: .type) { self.type = type } @@ -80,16 +76,16 @@ public class CarouselIndicatorModel: CarouselPagingModelProtocol { self.hybridThreshold = hybridThreshold } - if let currentIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .currentIndex) { - self.currentIndex = currentIndex - } - if let numberOfPages = try typeContainer.decodeIfPresent(Int.self, forKey: .numberOfPages) { self.numberOfPages = numberOfPages } - if let alwaysSendEvent = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysSendEvent) { - self.alwaysSendEvent = alwaysSendEvent + if let alwaysSendAction = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysSendAction) { + self.alwaysSendAction = alwaysSendAction + } + + if let padding = try typeContainer.decodeIfPresent(Float.self, forKey: .padding) { + self.padding = padding } if let isAnimated = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAnimated) { @@ -112,8 +108,8 @@ public class CarouselIndicatorModel: CarouselPagingModelProtocol { self.disabledIndicatorColor = disabledIndicatorColor } - if let indicatorTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .indicatorTintColor) { - self.indicatorTintColor = indicatorTintColor + if let indicatorColor = try typeContainer.decodeIfPresent(Color.self, forKey: .indicatorColor) { + self.indicatorColor = indicatorColor } if let currentIndicatorColor = try typeContainer.decodeIfPresent(Color.self, forKey: .currentIndicatorColor) { @@ -125,21 +121,17 @@ public class CarouselIndicatorModel: CarouselPagingModelProtocol { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) - try container.encodeIfPresent(barsColor, forKey: .barsColor) - try container.encodeIfPresent(currentBarColor, forKey: .currentBarColor) try container.encodeIfPresent(type, forKey: .type) try container.encodeIfPresent(hybridThreshold, forKey: .hybridThreshold) - try container.encodeIfPresent(barsColor, forKey: .barsColor) - try container.encodeIfPresent(currentBarColor, forKey: .currentBarColor) - try container.encodeIfPresent(currentIndex, forKey: .currentIndex) try container.encodeIfPresent(numberOfPages, forKey: .numberOfPages) - try container.encodeIfPresent(alwaysSendEvent, forKey: .alwaysSendEvent) + try container.encodeIfPresent(alwaysSendAction, forKey: .alwaysSendAction) try container.encodeIfPresent(isAnimated, forKey: .isAnimated) try container.encodeIfPresent(hidesForSinglePage, forKey: .hidesForSinglePage) try container.encodeIfPresent(accessibilityHasSlidesInsteadOfPage, forKey: .accessibilityHasSlidesInsteadOfPage) try container.encodeIfPresent(isEnabled, forKey: .isEnabled) try container.encodeIfPresent(disabledIndicatorColor, forKey: .disabledIndicatorColor) - try container.encodeIfPresent(indicatorTintColor, forKey: .indicatorTintColor) + try container.encodeIfPresent(indicatorColor, forKey: .indicatorColor) try container.encodeIfPresent(currentIndicatorColor, forKey: .currentIndicatorColor) + try container.encodeIfPresent(padding, forKey: .padding) } } diff --git a/MVMCoreUI/Models/ModelProtocols/CarouselPagingModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/CarouselPagingModelProtocol.swift index 94b1277a..27a35f87 100644 --- a/MVMCoreUI/Models/ModelProtocols/CarouselPagingModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/CarouselPagingModelProtocol.swift @@ -10,5 +10,5 @@ import Foundation public protocol CarouselPagingModelProtocol: MoleculeModelProtocol { - var position: Float? { get } + var padding: Float? { get } } diff --git a/MVMCoreUI/Organisms/Carousel.swift b/MVMCoreUI/Organisms/Carousel.swift index 928ce8da..17abe0e6 100644 --- a/MVMCoreUI/Organisms/Carousel.swift +++ b/MVMCoreUI/Organisms/Carousel.swift @@ -176,7 +176,7 @@ open class Carousel: View { pagingView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(molecule, delegateObject, false) as? (UIView & CarouselPageControlProtocol) } - addPaging(view: pagingView, position: (CGFloat(molecule?.position ?? 20))) + addPaging(view: pagingView, padding: (CGFloat(molecule?.padding ?? 20))) } /// Registers the cells with the collection view @@ -221,7 +221,7 @@ open class Carousel: View { } /// Adds a paging view. Centers it horizontally with the collection view. The position is the vertical distance from the center of the page view to the bottom of the collection view. - open func addPaging(view: (UIView & CarouselPageControlProtocol)?, position: CGFloat) { + open func addPaging(view: (UIView & CarouselPageControlProtocol)?, padding: CGFloat) { pagingView?.removeFromSuperview() bottomPin?.isActive = false @@ -234,7 +234,7 @@ open class Carousel: View { addSubview(pagingView) pagingView.centerXAnchor.constraint(equalTo: collectionView.centerXAnchor).isActive = true - collectionView.bottomAnchor.constraint(equalTo: pagingView.bottomAnchor, constant: position).isActive = true + collectionView.bottomAnchor.constraint(equalTo: pagingView.bottomAnchor, constant: padding).isActive = true bottomPin = bottomAnchor.constraint(equalTo: collectionView.bottomAnchor) bottomPin?.priority = .defaultLow bottomPin?.isActive = true