latest state

This commit is contained in:
Kevin G Christiano 2020-03-16 09:50:54 -04:00
parent ef5f864a02
commit 50920c83e0
9 changed files with 163 additions and 84 deletions

View File

@ -810,8 +810,8 @@
0A14F6B023E8C27A00EDF7F7 /* CarouselIndicator */ = { 0A14F6B023E8C27A00EDF7F7 /* CarouselIndicator */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
0A14F69223E349EF00EDF7F7 /* CarouselIndicator.swift */,
0A14F6A823E8750300EDF7F7 /* CarouselIndicatorModel.swift */, 0A14F6A823E8750300EDF7F7 /* CarouselIndicatorModel.swift */,
0A14F69223E349EF00EDF7F7 /* CarouselIndicator.swift */,
0AAF8E29240EA57D008DD263 /* BarsCarouselIndicatorModel.swift */, 0AAF8E29240EA57D008DD263 /* BarsCarouselIndicatorModel.swift */,
0A4253AE23F5C2C000554656 /* BarsIndicatorView.swift */, 0A4253AE23F5C2C000554656 /* BarsIndicatorView.swift */,
0AAF8E2B240EA594008DD263 /* NumericCarouselIndicatorModel.swift */, 0AAF8E2B240EA594008DD263 /* NumericCarouselIndicatorModel.swift */,

View File

@ -70,6 +70,9 @@ open class Arrow: View {
// MARK: - Drawing // MARK: - Drawing
//-------------------------------------------------- //--------------------------------------------------
/**
Draws the arrow pointing to the right and then rotates the arrow x degrees counter-clockwise.
*/
open override func draw(_ rect: CGRect) { open override func draw(_ rect: CGRect) {
super.draw(rect) super.draw(rect)

View File

@ -17,4 +17,33 @@ open class BarsCarouselIndicatorModel: CarouselIndicatorModel {
public class override var identifier: String { public class override var identifier: String {
return "barsCarouselIndicator" return "barsCarouselIndicator"
} }
public var currentIndicatorColor: Color = Color(uiColor: .mvmBlack)
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case currentIndicatorColor
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
public required init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
if let currentIndicatorColor = try typeContainer.decodeIfPresent(Color.self, forKey: .currentIndicatorColor) {
self.currentIndicatorColor = currentIndicatorColor
}
try super.init(from: decoder)
}
public override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(currentIndicatorColor, forKey: .currentIndicatorColor)
}
} }

View File

@ -14,7 +14,7 @@ open class BarsIndicatorView: CarouselIndicator {
// MARK: - Stored Properties // MARK: - Stored Properties
//-------------------------------------------------- //--------------------------------------------------
let stackView: StackView = { public let stackView: StackView = {
let stackView = StackView() let stackView = StackView()
stackView.axis = .horizontal stackView.axis = .horizontal
stackView.alignment = .bottom stackView.alignment = .bottom
@ -30,18 +30,49 @@ open class BarsIndicatorView: CarouselIndicator {
public static let indicatorBarWidth: CGFloat = 24 public static let indicatorBarWidth: CGFloat = 24
public static let indicatorBarHeight: (selected: CGFloat, unselected: CGFloat) = (selected: 4, unselected: 1) public static let indicatorBarHeight: (selected: CGFloat, unselected: CGFloat) = (selected: 4, unselected: 1)
/// Convenience to access the model.
public var barsCarouselIndicatorModel: BarsCarouselIndicatorModel? {
return model as? BarsCarouselIndicatorModel
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Computed Properties // MARK: - Computed Properties
//-------------------------------------------------- //--------------------------------------------------
open override var isEnabled: Bool { open override var isEnabled: Bool {
didSet { didSet {
barReferences.forEach { view, heightConstraint in barReferences.forEach { view, _ in
view.backgroundColor = isEnabled ? indicatorTintColor : disabledIndicatorColor view.backgroundColor = isEnabled ? indicatorColor : disabledIndicatorColor
} }
} }
} }
private(set) var _currentIndicatorColor: UIColor = .black
/// Colors the currently selected index, unique from other indicators
public var currentIndicatorColor: UIColor {
get { return _currentIndicatorColor }
set (newColor) {
_currentIndicatorColor = newColor
barsCarouselIndicatorModel?.currentIndicatorColor = Color(uiColor: newColor)
if !barReferences.isEmpty {
barReferences[currentIndex].view.backgroundColor = newColor
}
}
}
public override var indicatorColor: UIColor {
get { return _indicatorColor }
set (newColor) {
super.indicatorColor = newColor
for (i, barTuple) in barReferences.enumerated() where i != currentIndex {
barTuple.view.backgroundColor = newColor
}
}
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Initializers // MARK: - Initializers
//-------------------------------------------------- //--------------------------------------------------
@ -64,10 +95,15 @@ open class BarsIndicatorView: CarouselIndicator {
addSubview(stackView) addSubview(stackView)
isUserInteractionEnabled = false isUserInteractionEnabled = false
stackView.heightAnchor.constraint(equalToConstant: 4).isActive = true NSLayoutConstraint.activate([
stackView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true stackView.heightAnchor.constraint(equalToConstant: 4),
stackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true heightAnchor.constraint(equalTo: stackView.heightAnchor),
trailingAnchor.constraint(equalTo: stackView.trailingAnchor).isActive = true stackView.centerXAnchor.constraint(equalTo: centerXAnchor),
stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
stackView.topAnchor.constraint(equalTo: topAnchor),
bottomAnchor.constraint(equalTo: stackView.bottomAnchor),
trailingAnchor.constraint(equalTo: stackView.trailingAnchor)
])
} }
//-------------------------------------------------- //--------------------------------------------------
@ -81,7 +117,7 @@ open class BarsIndicatorView: CarouselIndicator {
for i in 0..<numberOfPages { for i in 0..<numberOfPages {
let bar = View() let bar = View()
bar.widthAnchor.constraint(equalToConstant: BarsIndicatorView.indicatorBarWidth).isActive = true bar.widthAnchor.constraint(equalToConstant: BarsIndicatorView.indicatorBarWidth).isActive = true
bar.backgroundColor = isEnabled ? indicatorTintColor : disabledIndicatorColor bar.backgroundColor = isEnabled ? (i == currentIndex ? currentIndicatorColor : indicatorColor) : disabledIndicatorColor
let barHeight = i == currentIndex ? BarsIndicatorView.indicatorBarHeight.selected : BarsIndicatorView.indicatorBarHeight.unselected let barHeight = i == currentIndex ? BarsIndicatorView.indicatorBarHeight.selected : BarsIndicatorView.indicatorBarHeight.unselected
let heightConstraint = bar.heightAnchor.constraint(equalToConstant: barHeight) let heightConstraint = bar.heightAnchor.constraint(equalToConstant: barHeight)
heightConstraint.isActive = true heightConstraint.isActive = true
@ -93,6 +129,19 @@ open class BarsIndicatorView: CarouselIndicator {
barReferences = bars barReferences = bars
} }
public override func assessTouchOf(_ touchPoint_X: CGFloat) {
currentIndex = barReferences.firstIndex { $0.0.frame.maxX >= touchPoint_X && $0.0.frame.minX <= touchPoint_X } ?? 0
}
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? BarsCarouselIndicatorModel else { return }
currentIndicatorColor = model.currentIndicatorColor.uiColor
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - IndicatorViewProtocol // MARK: - IndicatorViewProtocol
//-------------------------------------------------- //--------------------------------------------------
@ -111,7 +160,7 @@ open class BarsIndicatorView: CarouselIndicator {
} }
let expression = { let expression = {
self.barReferences[previousIndex].view.backgroundColor = self.indicatorTintColor self.barReferences[previousIndex].view.backgroundColor = self.indicatorColor
self.barReferences[newIndex].view.backgroundColor = self.currentIndicatorColor self.barReferences[newIndex].view.backgroundColor = self.currentIndicatorColor
self.barReferences[previousIndex].constraint.constant = BarsIndicatorView.indicatorBarHeight.unselected self.barReferences[previousIndex].constraint.constant = BarsIndicatorView.indicatorBarHeight.unselected
self.barReferences[newIndex].constraint.constant = BarsIndicatorView.indicatorBarHeight.selected self.barReferences[newIndex].constraint.constant = BarsIndicatorView.indicatorBarHeight.selected

View File

@ -48,11 +48,13 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol {
public var currentIndex: Int { public var currentIndex: Int {
get { return _currentIndex } get { return _currentIndex }
set (newIndex) { set (newIndex) {
carouselIndicatorModel?.currentIndex = newIndex
previousIndex = _currentIndex previousIndex = _currentIndex
_currentIndex = newIndex _currentIndex = newIndex
performAction() performAction()
updateUI(previousIndex: previousIndex, newIndex: newIndex, totalCount: numberOfPages, isAnimated: carouselIndicatorModel?.isAnimated ?? true) if previousIndex != newIndex {
updateUI(previousIndex: previousIndex, newIndex: newIndex, totalCount: numberOfPages, isAnimated: carouselIndicatorModel?.isAnimated ?? true)
}
} }
} }
@ -64,6 +66,7 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol {
get { return _numberOfPages } get { return _numberOfPages }
set (newTotal) { set (newTotal) {
guard _numberOfPages != newTotal else { return } guard _numberOfPages != newTotal else { return }
carouselIndicatorModel?.numberOfPages = newTotal
_numberOfPages = newTotal _numberOfPages = newTotal
isHidden = carouselIndicatorModel?.hidesForSinglePage ?? false && newTotal <= 1 isHidden = carouselIndicatorModel?.hidesForSinglePage ?? false && newTotal <= 1
@ -75,33 +78,12 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol {
return carouselIndicatorModel?.disabledIndicatorColor.uiColor ?? .mvmCoolGray3 return carouselIndicatorModel?.disabledIndicatorColor.uiColor ?? .mvmCoolGray3
} }
public var indicatorTintColor: UIColor { private(set) var _indicatorColor: UIColor = .black
get { return carouselIndicatorModel?.indicatorColor.uiColor ?? .black }
public var indicatorColor: UIColor {
get { return _indicatorColor }
set (newColor) { set (newColor) {
carouselIndicatorModel?.indicatorColor = Color(uiColor: newColor) carouselIndicatorModel?.indicatorColor = Color(uiColor: newColor)
// if isBarIndicator(), let barIndicator = indicatorView as? BarsIndicatorView {
// for (i, barTuple) in barIndicator.barReferences.enumerated() where i != currentIndex {
// barTuple.view.backgroundColor = newColor
// }
// }
}
}
private var _currentIndicatorColor: UIColor = .black
/// Colors the currently selected index, unique from other indicators
public var currentIndicatorColor: UIColor {
get { return _currentIndicatorColor }
set (newColor) {
_currentIndicatorColor = newColor
carouselIndicatorModel?.currentIndicatorColor = Color(uiColor: newColor)
// if isBarIndicator() {
// if let barIndicator = indicatorView as? BarsIndicatorView, !barIndicator.barReferences.isEmpty {
// barIndicator.barReferences[currentIndex].view.backgroundColor = newColor
// }
// }
} }
} }
@ -184,19 +166,11 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol {
let touchPoint = tapGesture?.location(in: self) let touchPoint = tapGesture?.location(in: self)
let touchPoint_X = touchPoint?.x ?? 0.0 let touchPoint_X = touchPoint?.x ?? 0.0
// if isBarIndicator(), let bars = (indicatorView as? BarsIndicatorView)?.barReferences { assessTouchOf(touchPoint_X)
// currentIndex = bars.firstIndex { $0.0.frame.maxX >= touchPoint_X && $0.0.frame.minX <= touchPoint_X } ?? 0
//
// } else {
// // Determine which half of the view was touched.
// if touchPoint_X > bounds.width / 2 {
// incrementCurrentIndex()
// } else {
// decrementCurrentIndex()
// }
// }
} }
func assessTouchOf(_ touchPoint_X: CGFloat) { }
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Methods // MARK: - Methods
//-------------------------------------------------- //--------------------------------------------------
@ -215,15 +189,13 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol {
// MARK: - MoleculeViewProtocol // MARK: - MoleculeViewProtocol
//-------------------------------------------------- //--------------------------------------------------
open override func set(with model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let model = model as? CarouselIndicatorModel else { return }
super.set(with: model, delegateObject, additionalData) super.set(with: model, delegateObject, additionalData)
// indicatorType = IndicatorType(rawValue: model.type) ?? .hybrid guard let model = model as? CarouselIndicatorModel else { return }
currentIndicatorColor = model.currentIndicatorColor.uiColor
indicatorTintColor = model.indicatorColor.uiColor indicatorColor = model.indicatorColor.uiColor
currentIndex = model.currentIndex
isEnabled = model.isEnabled isEnabled = model.isEnabled
if let accessibleValue = MVMCoreUIUtility.hardcodedString(withKey: model.accessibilityHasSlidesInsteadOfPage ? "MVMCoreUIPageControlslides_currentpage_index" : "MVMCoreUIPageControl_currentpage_index") { if let accessibleValue = MVMCoreUIUtility.hardcodedString(withKey: model.accessibilityHasSlidesInsteadOfPage ? "MVMCoreUIPageControlslides_currentpage_index" : "MVMCoreUIPageControl_currentpage_index") {

View File

@ -22,8 +22,10 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol {
public var moleculeName: String? public var moleculeName: String?
/// The maxmum count of pages before the indicatorView forces a Numeric Indicator in place of Bar. /// The maxmum count of pages before the indicatorView forces a Numeric Indicator in place of Bar.
public var numberOfPages: Int = 0 public var numberOfPages: Int = 0
// Sets the current Index to focus on.
public var currentIndex: Int = 0
public var isAnimated: Bool = true public var isAnimated: Bool = true
public var hidesForSinglePage: Bool = false 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 /// Set true to make the accessibility value as "Slide #currentPage of #totalPage", otherwise will be "Page #currentPage of #totalPage", default is false
@ -31,8 +33,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol {
public var isEnabled: Bool = true public var isEnabled: Bool = true
public var disabledIndicatorColor: Color = Color(uiColor: .mvmCoolGray3) public var disabledIndicatorColor: Color = Color(uiColor: .mvmCoolGray3)
public var indicatorColor: 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. /// Allows sendActions() to trigger even if index is already at min/max index.
public var alwaysSendAction = false public var alwaysSendAction = false
@ -44,7 +45,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol {
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case moleculeName case moleculeName
case backgroundColor case backgroundColor
case type case currentIndex
case numberOfPages case numberOfPages
case alwaysSendAction case alwaysSendAction
case isAnimated case isAnimated
@ -54,7 +55,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol {
case disabledIndicatorColor case disabledIndicatorColor
case indicatorColor case indicatorColor
case currentIndicatorColor case currentIndicatorColor
case padding case position
} }
//-------------------------------------------------- //--------------------------------------------------
@ -70,12 +71,16 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol {
self.numberOfPages = numberOfPages self.numberOfPages = numberOfPages
} }
if let currentIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .currentIndex) {
self.currentIndex = currentIndex
}
if let alwaysSendAction = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysSendAction) { if let alwaysSendAction = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysSendAction) {
self.alwaysSendAction = alwaysSendAction self.alwaysSendAction = alwaysSendAction
} }
if let padding = try typeContainer.decodeIfPresent(Float.self, forKey: .padding) { if let position = try typeContainer.decodeIfPresent(Float.self, forKey: .position) {
self.padding = padding self.position = position
} }
if let isAnimated = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAnimated) { if let isAnimated = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAnimated) {
@ -101,25 +106,21 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol {
if let indicatorColor = try typeContainer.decodeIfPresent(Color.self, forKey: .indicatorColor) { if let indicatorColor = try typeContainer.decodeIfPresent(Color.self, forKey: .indicatorColor) {
self.indicatorColor = indicatorColor self.indicatorColor = indicatorColor
} }
if let currentIndicatorColor = try typeContainer.decodeIfPresent(Color.self, forKey: .currentIndicatorColor) {
self.currentIndicatorColor = currentIndicatorColor
}
} }
public func encode(to encoder: Encoder) throws { public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self) var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(numberOfPages, forKey: .numberOfPages) try container.encode(numberOfPages, forKey: .numberOfPages)
try container.encodeIfPresent(alwaysSendAction, forKey: .alwaysSendAction) try container.encode(currentIndex, forKey: .currentIndex)
try container.encodeIfPresent(isAnimated, forKey: .isAnimated) try container.encode(alwaysSendAction, forKey: .alwaysSendAction)
try container.encode(isAnimated, forKey: .isAnimated)
try container.encodeIfPresent(hidesForSinglePage, forKey: .hidesForSinglePage) try container.encodeIfPresent(hidesForSinglePage, forKey: .hidesForSinglePage)
try container.encodeIfPresent(accessibilityHasSlidesInsteadOfPage, forKey: .accessibilityHasSlidesInsteadOfPage) try container.encodeIfPresent(accessibilityHasSlidesInsteadOfPage, forKey: .accessibilityHasSlidesInsteadOfPage)
try container.encodeIfPresent(isEnabled, forKey: .isEnabled) try container.encode(isEnabled, forKey: .isEnabled)
try container.encodeIfPresent(disabledIndicatorColor, forKey: .disabledIndicatorColor) try container.encode(disabledIndicatorColor, forKey: .disabledIndicatorColor)
try container.encodeIfPresent(indicatorColor, forKey: .indicatorColor) try container.encode(indicatorColor, forKey: .indicatorColor)
try container.encodeIfPresent(currentIndicatorColor, forKey: .currentIndicatorColor) try container.encodeIfPresent(position, forKey: .position)
try container.encodeIfPresent(padding, forKey: .padding)
} }
} }

View File

@ -40,9 +40,23 @@ open class NumericIndicatorView: CarouselIndicator {
open override var isEnabled: Bool { open override var isEnabled: Bool {
didSet { didSet {
pageCount.textColor = isEnabled ? indicatorTintColor : disabledIndicatorColor pageCount.textColor = isEnabled ? indicatorColor : disabledIndicatorColor
leftArrow.tintColor = isEnabled ? indicatorTintColor : disabledIndicatorColor leftArrow.tintColor = isEnabled ? indicatorColor : disabledIndicatorColor
rightArrow.tintColor = isEnabled ? indicatorTintColor : disabledIndicatorColor rightArrow.tintColor = isEnabled ? indicatorColor : disabledIndicatorColor
}
}
/// Sets the color for pageCount text, left arrow and right arrow.
public override var indicatorColor: UIColor {
get { return _indicatorColor }
set (newColor) {
super.indicatorColor = newColor
if isEnabled {
pageCount.textColor = newColor
leftArrow.tintColor = newColor
rightArrow.tintColor = newColor
}
} }
} }
@ -96,6 +110,15 @@ open class NumericIndicatorView: CarouselIndicator {
]) ])
} }
public override func assessTouchOf(_ touchPoint_X: CGFloat) {
if touchPoint_X > bounds.width / 2 {
incrementCurrentIndex()
} else {
decrementCurrentIndex()
}
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - IndicatorViewProtocol // MARK: - IndicatorViewProtocol
//-------------------------------------------------- //--------------------------------------------------

View File

@ -10,5 +10,5 @@ import Foundation
public protocol CarouselPagingModelProtocol: MoleculeModelProtocol { public protocol CarouselPagingModelProtocol: MoleculeModelProtocol {
var padding: Float? { get } var position: Float? { get }
} }

View File

@ -176,7 +176,7 @@ open class Carousel: View {
pagingView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(molecule, delegateObject, false) as? (UIView & CarouselPageControlProtocol) pagingView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(molecule, delegateObject, false) as? (UIView & CarouselPageControlProtocol)
} }
addPaging(view: pagingView, padding: (CGFloat(molecule?.padding ?? 20))) addPaging(view: pagingView, position: (CGFloat(molecule?.position ?? 20)))
} }
/// Registers the cells with the collection view /// 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. /// 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)?, padding: CGFloat) { open func addPaging(view: (UIView & CarouselPageControlProtocol)?, position: CGFloat) {
pagingView?.removeFromSuperview() pagingView?.removeFromSuperview()
bottomPin?.isActive = false bottomPin?.isActive = false
@ -234,13 +234,15 @@ open class Carousel: View {
addSubview(pagingView) addSubview(pagingView)
pagingView.centerXAnchor.constraint(equalTo: collectionView.centerXAnchor).isActive = true pagingView.centerXAnchor.constraint(equalTo: collectionView.centerXAnchor).isActive = true
collectionView.bottomAnchor.constraint(equalTo: pagingView.bottomAnchor, constant: padding).isActive = true collectionView.bottomAnchor.constraint(equalTo: pagingView.centerYAnchor, constant: position).isActive = true
bottomAnchor.constraint(greaterThanOrEqualTo: pagingView.bottomAnchor).isActive = true
bottomPin = bottomAnchor.constraint(equalTo: collectionView.bottomAnchor) bottomPin = bottomAnchor.constraint(equalTo: collectionView.bottomAnchor)
bottomPin?.priority = .defaultLow bottomPin?.priority = .defaultLow
bottomPin?.isActive = true bottomPin?.isActive = true
pagingView.numberOfPages = numberOfPages pagingView.numberOfPages = numberOfPages
(pagingView as? MVMCoreUIViewConstrainingProtocol)?.alignHorizontal?(.fill) (pagingView as? MVMCoreUIViewConstrainingProtocol)?.alignHorizontal?(.fill)
pageIndex = pagingView.currentIndex
pagingView.indicatorTouchAction = { [weak self] pager in pagingView.indicatorTouchAction = { [weak self] pager in
DispatchQueue.main.async { DispatchQueue.main.async {
guard let self = self else { return } guard let self = self else { return }