getting ready for an evolution
This commit is contained in:
parent
8832bbd0b7
commit
af54ac2a3c
@ -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 {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user