Digital ACT-191 ONEAPP-7013 story: added listeners to perform actions
This commit is contained in:
parent
8a8bb73da3
commit
ba1ffdf390
@ -91,10 +91,11 @@ open class Carousel: View {
|
|||||||
|
|
||||||
/// Enum used to describe the pagination display for this component.
|
/// Enum used to describe the pagination display for this component.
|
||||||
public enum PaginationDisplay: String, CaseIterable {
|
public enum PaginationDisplay: String, CaseIterable {
|
||||||
case onHover, persistent, none
|
case persistent, none
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enum used to describe the peek for this component. Options for user to configure the partially-visible tile in group. Setting peek to 'none' will display arrow navigation icons on mobile devices.
|
/// Enum used to describe the peek for this component.
|
||||||
|
/// This is how much a tile is partially visible. It is measured by the distance between the edge of the tile and the edge of the viewport or carousel container. A peek can appear on the left and/or right edge of the carousel container or viewport, depending on the carousel’s scroll position.
|
||||||
public enum Peek: String, CaseIterable {
|
public enum Peek: String, CaseIterable {
|
||||||
case standard, minimum, none
|
case standard, minimum, none
|
||||||
}
|
}
|
||||||
@ -157,7 +158,7 @@ open class Carousel: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The amount of slides visible in the carousel container at one time. The default value will be 3UP in tablet and 1UP in mobile.
|
/// The amount of slides visible in the carousel container at one time. The default value will be 3UP in tablet and 1UP in mobile.
|
||||||
open var layout: Layout {
|
open var layout: CarouselScrollbar.Layout {
|
||||||
get { return _layout }
|
get { return _layout }
|
||||||
set {
|
set {
|
||||||
_layout = newValue
|
_layout = newValue
|
||||||
@ -197,7 +198,7 @@ open class Carousel: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If provided, will apply margin to pagination arrows. Can be set to either positive or negative values.
|
/// If provided, will apply margin to pagination arrows. Can be set to either positive or negative values.
|
||||||
/// The default value will be 12px in tablet and 8px in mobile.
|
/// The default value will be 12px in tablet and 8px in mobile.
|
||||||
open var paginationInset: CGFloat {
|
open var paginationInset: CGFloat {
|
||||||
get { return _paginationInset }
|
get { return _paginationInset }
|
||||||
@ -279,7 +280,7 @@ open class Carousel: View {
|
|||||||
open var onChangePublisher = PassthroughSubject<Int, Never>()
|
open var onChangePublisher = PassthroughSubject<Int, Never>()
|
||||||
private var onChangeCancellable: AnyCancellable?
|
private var onChangeCancellable: AnyCancellable?
|
||||||
|
|
||||||
internal var _layout: Layout = UIDevice.isIPad ? .threeUP : .oneUP
|
internal var _layout: CarouselScrollbar.Layout = UIDevice.isIPad ? .threeUP : .oneUP
|
||||||
internal var _pagination: CarouselPaginationModel = .init(kind: .lowContrast, floating: true)
|
internal var _pagination: CarouselPaginationModel = .init(kind: .lowContrast, floating: true)
|
||||||
internal var _paginationDisplay: PaginationDisplay = .none
|
internal var _paginationDisplay: PaginationDisplay = .none
|
||||||
internal var _paginationInset: CGFloat = UIDevice.isIPad ? VDSLayout.space3X : VDSLayout.space2X
|
internal var _paginationInset: CGFloat = UIDevice.isIPad ? VDSLayout.space3X : VDSLayout.space2X
|
||||||
@ -294,6 +295,7 @@ open class Carousel: View {
|
|||||||
|
|
||||||
// The scrollbar has top 5X space. So the expected top space is adjusted for tablet and mobile.
|
// The scrollbar has top 5X space. So the expected top space is adjusted for tablet and mobile.
|
||||||
let scrollbarTopSpace = UIDevice.isIPad ? VDSLayout.space3X : VDSLayout.space1X
|
let scrollbarTopSpace = UIDevice.isIPad ? VDSLayout.space3X : VDSLayout.space1X
|
||||||
|
|
||||||
var slotHeight = 100.0
|
var slotHeight = 100.0
|
||||||
var peekMinimum = 24.0
|
var peekMinimum = 24.0
|
||||||
var minimumSlotWidth = 0.0
|
var minimumSlotWidth = 0.0
|
||||||
@ -351,7 +353,19 @@ open class Carousel: View {
|
|||||||
|
|
||||||
open override func updateView() {
|
open override func updateView() {
|
||||||
super.updateView()
|
super.updateView()
|
||||||
|
|
||||||
|
carouselScrollBar.numberOfSlides = data.count
|
||||||
|
carouselScrollBar.position = (carouselScrollBar.position == 0 || carouselScrollBar.position > carouselScrollBar.numberOfSlides) ? 1 : carouselScrollBar.position
|
||||||
|
carouselScrollBar.layout = _layout
|
||||||
|
carouselScrollBar.isHidden = (Int((Float(carouselScrollBar.numberOfSlides)) * Float(carouselScrollBar._layout.value)) <= 1) ? true : false
|
||||||
|
|
||||||
|
// When peek is set to ‘none,’ pagination controls are automatically set to persistent.
|
||||||
|
if peek == .none {
|
||||||
|
paginationDisplay = .persistent
|
||||||
|
}
|
||||||
|
|
||||||
containerViewHeightConstraint?.isActive = false
|
containerViewHeightConstraint?.isActive = false
|
||||||
|
containerStackHeightConstraint?.isActive = false
|
||||||
updatePaginationControls()
|
updatePaginationControls()
|
||||||
getSlotWidth()
|
getSlotWidth()
|
||||||
|
|
||||||
@ -363,11 +377,11 @@ open class Carousel: View {
|
|||||||
|
|
||||||
// add carousel items
|
// add carousel items
|
||||||
if data.count > 0 {
|
if data.count > 0 {
|
||||||
var xPos = gutter.value
|
var xPos = 0.0
|
||||||
for _ in 0...data.count - 1 {
|
for x in 0...data.count - 1 {
|
||||||
let carouselSlot = View().with {
|
let carouselSlot = View().with {
|
||||||
$0.clipsToBounds = true
|
$0.clipsToBounds = true
|
||||||
$0.backgroundColor = .lightGray
|
$0.backgroundColor = UIColor(red: CGFloat(216) / 255.0, green: CGFloat(218) / 255.0, blue: CGFloat(218) / 255.0, alpha: 1)
|
||||||
}
|
}
|
||||||
scrollView.addSubview(carouselSlot)
|
scrollView.addSubview(carouselSlot)
|
||||||
carouselSlot
|
carouselSlot
|
||||||
@ -379,25 +393,74 @@ open class Carousel: View {
|
|||||||
xPos = xPos + minimumSlotWidth + gutter.value
|
xPos = xPos + minimumSlotWidth + gutter.value
|
||||||
}
|
}
|
||||||
scrollView.heightAnchor.constraint(equalToConstant: slotHeight).isActive = true
|
scrollView.heightAnchor.constraint(equalToConstant: slotHeight).isActive = true
|
||||||
scrollView.contentSize = CGSize(width: xPos-minimumSlotWidth, height: slotHeight)
|
scrollView.contentSize = CGSize(width: xPos - gutter.value, height: slotHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
let containerHeight = slotHeight + scrollbarTopSpace + containerSize.height
|
let containerHeight = slotHeight + scrollbarTopSpace + containerSize.height
|
||||||
containerViewHeightConstraint = containerView.heightAnchor.constraint(equalToConstant: containerHeight)
|
if carouselScrollBar.isHidden {
|
||||||
|
containerStackHeightConstraint = contentStackView.heightAnchor.constraint(equalToConstant: slotHeight)
|
||||||
|
containerViewHeightConstraint = containerView.heightAnchor.constraint(equalToConstant: slotHeight)
|
||||||
|
} else {
|
||||||
|
containerStackHeightConstraint = contentStackView.heightAnchor.constraint(equalToConstant: containerHeight)
|
||||||
|
containerViewHeightConstraint = containerView.heightAnchor.constraint(equalToConstant: containerHeight)
|
||||||
|
}
|
||||||
containerViewHeightConstraint?.isActive = true
|
containerViewHeightConstraint?.isActive = true
|
||||||
|
containerStackHeightConstraint?.isActive = true
|
||||||
|
|
||||||
|
addlisteners()
|
||||||
layoutIfNeeded()
|
layoutIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
|
for subview in subviews {
|
||||||
|
for recognizer in subview.gestureRecognizers ?? [] {
|
||||||
|
subview.removeGestureRecognizer(recognizer)
|
||||||
|
}
|
||||||
|
}
|
||||||
super.reset()
|
super.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Private Methods
|
// MARK: - Private Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
func addlisteners() {
|
||||||
|
nextButton.onClick = { _ in self.nextButtonClick() }
|
||||||
|
previousButton.onClick = { _ in self.previousButtonClick() }
|
||||||
|
|
||||||
|
//setup test page to show scrubber id was changed
|
||||||
|
// carouselScrollBar.onScrubberDrag = { [weak self] scrubberId in
|
||||||
|
// guard let self else { return }
|
||||||
|
// updateScrollPosition(position: scrubberId, callbackText:"onScrubberDrag")
|
||||||
|
// }
|
||||||
|
|
||||||
|
/// will be called when the thumb move forward.
|
||||||
|
carouselScrollBar.onMoveForward = { [weak self] scrubberId in
|
||||||
|
guard let self else { return }
|
||||||
|
updateScrollPosition(position: scrubberId, callbackText:"onMoveForward")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// will be called when the thumb move backward.
|
||||||
|
carouselScrollBar.onMoveBackward = { [weak self] scrubberId in
|
||||||
|
guard let self else { return }
|
||||||
|
updateScrollPosition(position: scrubberId, callbackText:"onMoveBackward")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// will be called when the thumb touch start.
|
||||||
|
carouselScrollBar.onThumbTouchStart = { [weak self] scrubberId in
|
||||||
|
guard let self else { return }
|
||||||
|
updateScrollPosition(position: scrubberId, callbackText:"onThumbTouchStart")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// will be called when the thumb touch end.
|
||||||
|
carouselScrollBar.onThumbTouchEnd = { [weak self] scrubberId in
|
||||||
|
guard let self else { return }
|
||||||
|
updateScrollPosition(position: scrubberId, callbackText:"onThumbTouchEnd")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updatePaginationControls() {
|
func updatePaginationControls() {
|
||||||
containerView.surface = surface
|
containerView.surface = surface
|
||||||
previousButton.isHidden = (paginationDisplay == .none)
|
showPaginationControls()
|
||||||
nextButton.isHidden = (paginationDisplay == .none)
|
|
||||||
previousButton.kind = pagination.kind
|
previousButton.kind = pagination.kind
|
||||||
previousButton.floating = pagination.floating
|
previousButton.floating = pagination.floating
|
||||||
nextButton.kind = pagination.kind
|
nextButton.kind = pagination.kind
|
||||||
@ -419,4 +482,43 @@ open class Carousel: View {
|
|||||||
}
|
}
|
||||||
minimumSlotWidth = minimumSlotWidth / CGFloat(layout.value)
|
minimumSlotWidth = minimumSlotWidth / CGFloat(layout.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func nextButtonClick() {
|
||||||
|
carouselScrollBar.position = carouselScrollBar.position+1
|
||||||
|
showPaginationControls()
|
||||||
|
updateScrollPosition(position: carouselScrollBar.position, callbackText:"pageControlClicks")
|
||||||
|
}
|
||||||
|
|
||||||
|
func previousButtonClick() {
|
||||||
|
carouselScrollBar.position = carouselScrollBar.position-1
|
||||||
|
showPaginationControls()
|
||||||
|
updateScrollPosition(position: carouselScrollBar.position, callbackText:"pageControlClicks")
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateScrollPosition(position: Int, callbackText: String) {
|
||||||
|
if carouselScrollBar.numberOfSlides > 0 {
|
||||||
|
let contentOffsetWidth = scrollView.contentSize.width
|
||||||
|
let totalPositions = totalPositions()
|
||||||
|
let multiplier: Float = (position == 1) ? 0 : Float((position)-1) / Float(totalPositions)
|
||||||
|
let xPos = (position == totalPositions) ? (contentOffsetWidth - containerView.frame.size.width) : CGFloat(Float(contentOffsetWidth) * multiplier)
|
||||||
|
carouselScrollBar.scrubberId = position
|
||||||
|
let yPos = scrollView.contentOffset.y
|
||||||
|
scrollView.setContentOffset(CGPoint(x: xPos, y: yPos), animated: true)
|
||||||
|
showPaginationControls()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func totalPositions() -> Int {
|
||||||
|
return Int (ceil (Double(carouselScrollBar.numberOfSlides) / Double(_layout.value)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func showPaginationControls() {
|
||||||
|
if carouselScrollBar.numberOfSlides == _layout.value {
|
||||||
|
previousButton.isHidden = true
|
||||||
|
nextButton.isHidden = true
|
||||||
|
} else {
|
||||||
|
previousButton.isHidden = (carouselScrollBar.position == 1) || (paginationDisplay == .none)
|
||||||
|
nextButton.isHidden = (carouselScrollBar.position == totalPositions()) || (paginationDisplay == .none)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user