Digital ACT-191 ONEAPP-6830 story: update position when scroll thumb drag / on move forward / backward

This commit is contained in:
vasavk 2024-03-21 12:00:03 +05:30
parent 51a00f9b68
commit 1387cb6bf4

View File

@ -112,6 +112,8 @@ open class CarouselScrollbar: View {
/// Allows a unique id to be passed into the thumb and track of the thumb(scrubber). /// Allows a unique id to be passed into the thumb and track of the thumb(scrubber).
open var scrubberId: Int? { didSet { setNeedsUpdate() } } open var scrubberId: Int? { didSet { setNeedsUpdate() } }
/// A callback when the scrubber position changes. Passes parameters (position).
open var onScrubberDidChange: ((Int) -> Void)?
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Private Properties // MARK: - Private Properties
@ -241,29 +243,32 @@ open class CarouselScrollbar: View {
// MARK: - Private Methods // MARK: - Private Methods
//-------------------------------------------------- //--------------------------------------------------
func onMoveBackward() { func onMoveBackward() {
thumbView.frame.origin.x = thumbView.frame.origin.x - CGFloat(actualThumbWidth) position = (position ?? 1) - 1
updateActiveOverlays() scrollThumbToPosition(position)
} }
func onMoveForward() { func onMoveForward() {
thumbView.frame.origin.x = thumbView.frame.origin.x + CGFloat(actualThumbWidth) position = (position ?? 1) + 1
updateActiveOverlays() scrollThumbToPosition(position)
} }
// Drag scrollbar thumb to move it to the left or right.
// Upon releases of drag, the scrollbar thumb snaps to the closest full position and the scrollbar returns to original size without delay.
@objc func onScrubberDrag(_ sender: UIPanGestureRecognizer) { @objc func onScrubberDrag(_ sender: UIPanGestureRecognizer) {
let translation = sender.translation(in: thumbView) let translation = sender.translation(in: thumbView)
if sender.state == UIGestureRecognizer.State.began { if sender.state == UIGestureRecognizer.State.began {
trayOriginalCenter = thumbView.center trayOriginalCenter = thumbView.center
} else if sender.state == UIGestureRecognizer.State.changed { } else if sender.state == UIGestureRecognizer.State.changed {
let movePositions = Int (ceil (Double(translation.x) / Double(actualThumbWidth))) let draggedPositions = Int (ceil (Double(translation.x) / Double(actualThumbWidth)))
setThumb(at: (position ?? 1) + movePositions) setThumb(at: (position ?? 1) + draggedPositions)
} }
else if sender.state == UIGestureRecognizer.State.cancelled || sender.state == UIGestureRecognizer.State.ended { else if sender.state == UIGestureRecognizer.State.cancelled || sender.state == UIGestureRecognizer.State.ended {
let movePositions = Int (ceil (Double(translation.x) / Double(actualThumbWidth))) let draggedPositions = Int (ceil (Double(translation.x) / Double(actualThumbWidth)))
position = (position ?? 1) + movePositions position = (((position ?? 1) + draggedPositions) < 1) ? 1 : ((position ?? 1) + draggedPositions)
} }
} }
// Move the scrollbar thumb to the left while tapping on the left side of the scrubber.
@objc func onThumbTouchStart(_ gesture: UILongPressGestureRecognizer) { @objc func onThumbTouchStart(_ gesture: UILongPressGestureRecognizer) {
if gesture.state == .began { if gesture.state == .began {
leftActiveOverlay.backgroundColor = activeOverlayColorConfiguration.getColor(self) leftActiveOverlay.backgroundColor = activeOverlayColorConfiguration.getColor(self)
@ -274,12 +279,11 @@ open class CarouselScrollbar: View {
} else if gesture.state == .ended { } else if gesture.state == .ended {
leftActiveOverlay.backgroundColor = .clear leftActiveOverlay.backgroundColor = .clear
leftActiveOverlay.layer.opacity = defaultOpacity leftActiveOverlay.layer.opacity = defaultOpacity
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { [weak self] in self.onMoveBackward()
self?.onMoveBackward()
}
} }
} }
// Move the scrollbar thumb to the right while tapping on the right side of the scrubber.
@objc func onThumbTouchEnd(_ gesture: UILongPressGestureRecognizer) { @objc func onThumbTouchEnd(_ gesture: UILongPressGestureRecognizer) {
if gesture.state == .began { if gesture.state == .began {
rightActiveOverlay.backgroundColor = activeOverlayColorConfiguration.getColor(self) rightActiveOverlay.backgroundColor = activeOverlayColorConfiguration.getColor(self)
@ -290,12 +294,12 @@ open class CarouselScrollbar: View {
} else if gesture.state == .ended { } else if gesture.state == .ended {
rightActiveOverlay.backgroundColor = .clear rightActiveOverlay.backgroundColor = .clear
rightActiveOverlay.layer.opacity = defaultOpacity rightActiveOverlay.layer.opacity = defaultOpacity
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { [weak self] in self.onMoveForward()
self?.onMoveForward()
}
} }
} }
// Minimum thumb width applied
// Incomplete set moves a shorter distance than the standard increment value.
private func setThumbWidth() { private func setThumbWidth() {
let width = (Float(trackViewWidth) / Float(numberOfSlides ?? 1)) * Float(_selectedLayout.value) let width = (Float(trackViewWidth) / Float(numberOfSlides ?? 1)) * Float(_selectedLayout.value)
actualThumbWidth = (width > Float(trackViewWidth)) ? Float(trackViewWidth) : width actualThumbWidth = (width > Float(trackViewWidth)) ? Float(trackViewWidth) : width
@ -306,6 +310,7 @@ open class CarouselScrollbar: View {
updateActiveOverlays() updateActiveOverlays()
} }
// Update active overlay frames according to thumb position.
private func updateActiveOverlays() { private func updateActiveOverlays() {
// adjusting thumb position if it goes beyond trackView. // adjusting thumb position if it goes beyond trackView.
let thumbPosition = thumbView.frame.origin.x + thumbView.frame.size.width let thumbPosition = thumbView.frame.origin.x + thumbView.frame.size.width
@ -331,6 +336,7 @@ open class CarouselScrollbar: View {
private func scrollThumbToPosition(_ position: Int?) { private func scrollThumbToPosition(_ position: Int?) {
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { [weak self] in DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { [weak self] in
self?.setThumb(at: position) self?.setThumb(at: position)
self?.onScrubberDidChange?(position ?? 1)
} }
} }