getting ready for an evolution

This commit is contained in:
Kevin G Christiano 2020-01-31 15:38:07 -05:00
parent 8832bbd0b7
commit af54ac2a3c

View File

@ -8,16 +8,11 @@
import Foundation import Foundation
public protocol PagingIndicatorProtocol: class { /**
typealias PagingTouchBlock = (PagingIndicatorProtocol) -> () This class is implemented to focus primarily on the page control logic.
var currentPage: Int { get } Visual flourishes and bespoke behavior should be subclassed from here.
var numberOfPages: Int { get } */
// func setPagingTouchBlock(_ pagingTouchBlock: PagingTouchBlock?) open class PageControl: Control {
// func scrollViewDidScroll(_ collectionView: UICollectionView)
}
open class PageControl: Control, PagingIndicatorProtocol {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Constraints // MARK: - Constraints
//-------------------------------------------------- //--------------------------------------------------
@ -38,18 +33,19 @@ open class PageControl: Control, PagingIndicatorProtocol {
public var indicatorType: IndicatorType = .hybrid public var indicatorType: IndicatorType = .hybrid
public var indicatorSpacing: CGFloat { public var indicatorSpacing: CGFloat {
get { return containerStack.spacing } get { return stackView.spacing }
set { set {
containerStack.spacing = newValue stackView.spacing = newValue
containerStack.layoutIfNeeded() stackView.layoutIfNeeded()
} }
} }
public let indicatorBarWidth: CGFloat = 24 public let indicatorBarWidth: CGFloat = 24
public let indicatorBarHeight: (selected: CGFloat, unselected: CGFloat) = (selected: 4, unselected: 1) public let indicatorBarHeight: (selected: CGFloat, unselected: CGFloat) = (selected: 4, unselected: 1)
private(set) var indicators = [BarIndicator]() private(set) var indicators = [BarIndicator]()
var containerStack: StackView = { var stackView: StackView = {
let stack = StackView() let stack = StackView()
stack.axis = .horizontal stack.axis = .horizontal
stack.distribution = .equalSpacing stack.distribution = .equalSpacing
@ -57,11 +53,13 @@ open class PageControl: Control, PagingIndicatorProtocol {
return stack return stack
}() }()
public var pagingTouchBlock: PagingIndicatorProtocol.PagingTouchBlock? public var pagingTouchBlock: ((Int)->())?
// a flag to allow to send UIControlEventValueChanged actions all the time // a flag to allow to send UIControlEventValueChanged actions all the time
// e.g. going to previous element at first place and going to next at last place // e.g. going to previous element at first place and going to next at last place
// While current rectangle won't change, need update current page // While current rectangle won't change, need update current page
// When awlaysSenfingControlEvent is false, and user is already at first or final index, if user try to increment or decrement, won't do action
// while self.awlaysSenfingControlEven is YES, it still send control event, while the rectangle won't change, need set currentPage again.
public var alwaysSendingControlEvent = false public var alwaysSendingControlEvent = 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
@ -69,6 +67,9 @@ open class PageControl: Control, PagingIndicatorProtocol {
public var isAnimated = false public var isAnimated = false
public var hidesForSinglePage = false public var hidesForSinglePage = false
/// If true, then index will wraparound, otherwise it will stop paging at min/max index.
public var allowIndexWraparound = false
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Computed Properties // MARK: - Computed Properties
//-------------------------------------------------- //--------------------------------------------------
@ -165,21 +166,21 @@ open class PageControl: Control, PagingIndicatorProtocol {
open override func setupView() { open override func setupView() {
super.setupView() super.setupView()
if containerStack.subviews.isEmpty { if stackView.subviews.isEmpty {
if let accessibleValue = MVMCoreUIUtility.hardcodedString(withKey: isSlidesAccessibile ? "MVMCoreUIPageControlslides_currentpage_index" : "MVMCoreUIPageControl_currentpage_index") { if let accessibleValue = MVMCoreUIUtility.hardcodedString(withKey: isSlidesAccessibile ? "MVMCoreUIPageControlslides_currentpage_index" : "MVMCoreUIPageControl_currentpage_index") {
accessibilityValue = String(format: accessibleValue, currentPage + 1, numberOfPages) accessibilityValue = String(format: accessibleValue, currentPage + 1, numberOfPages)
} }
addSubview(containerStack) addSubview(stackView)
containerStack.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true stackView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
containerStack.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor).isActive = true stackView.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor).isActive = true
trailingAnchor.constraint(lessThanOrEqualTo: containerStack.trailingAnchor).isActive = true trailingAnchor.constraint(lessThanOrEqualTo: stackView.trailingAnchor).isActive = true
topConstraint = containerStack.topAnchor.constraint(equalTo: topAnchor, constant: PaddingThree) topConstraint = stackView.topAnchor.constraint(equalTo: topAnchor, constant: PaddingThree)
topConstraint?.priority = .defaultHigh topConstraint?.priority = .defaultHigh
topConstraint?.isActive = true topConstraint?.isActive = true
bottomConstraint = bottomAnchor.constraint(equalTo: containerStack.bottomAnchor, constant: PaddingThree) bottomConstraint = bottomAnchor.constraint(equalTo: stackView.bottomAnchor, constant: PaddingThree)
bottomConstraint?.priority = .defaultHigh bottomConstraint?.priority = .defaultHigh
bottomConstraint?.isActive = true bottomConstraint?.isActive = true
@ -231,7 +232,7 @@ open class PageControl: Control, PagingIndicatorProtocol {
func indicatorTapped(_ tapGesture: UITapGestureRecognizer?) { func indicatorTapped(_ tapGesture: UITapGestureRecognizer?) {
if isUserInteractionEnabled { if isUserInteractionEnabled {
let touchPoint_X = tapGesture?.location(in: containerStack).x ?? 0.0 let touchPoint_X = tapGesture?.location(in: stackView).x ?? 0.0
let index = indicators.firstIndex { indicator in let index = indicators.firstIndex { indicator in
return indicator.frame.maxX >= touchPoint_X && indicator.frame.minX <= touchPoint_X return indicator.frame.maxX >= touchPoint_X && indicator.frame.minX <= touchPoint_X
@ -240,7 +241,7 @@ open class PageControl: Control, PagingIndicatorProtocol {
if let selectIndex = index { if let selectIndex = index {
currentPage = selectIndex currentPage = selectIndex
sendActions(for: .valueChanged) sendActions(for: .valueChanged)
pagingTouchBlock?(self) pagingTouchBlock?(selectIndex)
} }
} }
} }
@ -287,21 +288,19 @@ open class PageControl: Control, PagingIndicatorProtocol {
accessibilityAdjust(toPage: currentPage - 1) accessibilityAdjust(toPage: currentPage - 1)
} }
// When awlaysSenfingControlEvent is false, and user is already at first or final index, if user try to increment or decrement, won't do action
// while self.awlaysSenfingControlEven is YES, it still send control event, while the rectangle won't change, need set currentPage again.
func accessibilityAdjust(toPage index: Int) { func accessibilityAdjust(toPage index: Int) {
if (index < numberOfPages && index >= 0) || alwaysSendingControlEvent { if (index < numberOfPages && index >= 0) || alwaysSendingControlEvent {
isAnimated = false isAnimated = false
currentPage = index currentPage = index
sendActions(for: .valueChanged) sendActions(for: .valueChanged)
pagingTouchBlock?(self) pagingTouchBlock?(index)
} }
} }
func setTopBottomSpace(constant: CGFloat) { func setTopBottomSpace(constant: CGFloat) {
self.bottomConstraint?.constant = constant bottomConstraint?.constant = constant
self.topConstraint?.constant = constant topConstraint?.constant = constant
} }
public class BarIndicator: View { public class BarIndicator: View {