transitioning logical view model separation
This commit is contained in:
parent
3e3b7dac79
commit
b00485c81a
@ -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()
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,5 +10,5 @@ import Foundation
|
||||
|
||||
|
||||
public protocol CarouselPagingModelProtocol: MoleculeModelProtocol {
|
||||
var position: Float? { get }
|
||||
var padding: Float? { get }
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user