Digital ACT-191 ONEAPP-6830 story: Implementation for scroll thumb on given position value

This commit is contained in:
vasavk 2024-03-21 09:32:00 +05:30
parent fadb996c6e
commit f7ef52251b

View File

@ -44,11 +44,12 @@ open class CarouselScrollbar: View {
_numberOfSlides = 1 _numberOfSlides = 1
} }
setThumbWidth() setThumbWidth()
setThumb(position)
setNeedsUpdate() setNeedsUpdate()
} }
} }
/// The amount of slides visible in the carousel container at one time. /// The number of slides that can appear at once in a set in a carousel container.
open var selectedLayout: Layout? { open var selectedLayout: Layout? {
get { return _selectedLayout } get { return _selectedLayout }
set { set {
@ -58,11 +59,12 @@ open class CarouselScrollbar: View {
_selectedLayout = .oneUP _selectedLayout = .oneUP
} }
setThumbWidth() setThumbWidth()
setThumb(position)
setNeedsUpdate() setNeedsUpdate()
} }
} }
/// Enum used to describe the amount of slides visible in the carousel container at one time. /// Enum used to describe the number of slides that can appear at once in a set in a carousel container.
public enum Layout: String, CaseIterable { public enum Layout: String, CaseIterable {
case oneUP = "1UP" case oneUP = "1UP"
case twoUP = "2UP" case twoUP = "2UP"
@ -93,7 +95,19 @@ open class CarouselScrollbar: View {
} }
/// Used to set the position of the thumb(scrubber). This is used when the carousel container changes position, it will align the position of thumb(scrubber). /// Used to set the position of the thumb(scrubber). This is used when the carousel container changes position, it will align the position of thumb(scrubber).
open var position: Int? { didSet { setNeedsUpdate() } } open var position: Int? {
get { return _position }
set {
if let newValue {
checkPositions()
_position = (newValue > totalPositions ?? 1) ? totalPositions : newValue
} else {
_position = 1
}
setThumb(position)
setNeedsUpdate()
}
}
/// 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() } }
@ -107,6 +121,8 @@ open class CarouselScrollbar: View {
internal var _selectedLayout: Layout = .oneUP internal var _selectedLayout: Layout = .oneUP
internal var _numberOfSlides: Int? = 1 internal var _numberOfSlides: Int? = 1
internal var heightConstraint: NSLayoutConstraint? internal var heightConstraint: NSLayoutConstraint?
internal var totalPositions: Int? = 1
internal var _position: Int? = 1
private let trackViewWidth = 96 private let trackViewWidth = 96
private let trackViewHeight: CGFloat = 4 private let trackViewHeight: CGFloat = 4
@ -179,7 +195,7 @@ open class CarouselScrollbar: View {
leftActiveOverlay.frame = CGRectMake(trackView.frame.origin.x, 20, CGFloat(trackViewWidth), trackViewHeight) leftActiveOverlay.frame = CGRectMake(trackView.frame.origin.x, 20, CGFloat(trackViewWidth), trackViewHeight)
leftActiveOverlay.isUserInteractionEnabled = true leftActiveOverlay.isUserInteractionEnabled = true
leftActiveOverlay.layer.cornerRadius = cornerRadius leftActiveOverlay.layer.cornerRadius = cornerRadius
let leftPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.leftLongPressed(_:))) let leftPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.onThumbTouchStart(_:)))
leftPressRecognizer.minimumPressDuration = 0 leftPressRecognizer.minimumPressDuration = 0
leftActiveOverlay.addGestureRecognizer(leftPressRecognizer) leftActiveOverlay.addGestureRecognizer(leftPressRecognizer)
addSubview(leftActiveOverlay) addSubview(leftActiveOverlay)
@ -188,7 +204,7 @@ open class CarouselScrollbar: View {
rightActiveOverlay.frame = CGRectMake(thumbView.frame.origin.x + thumbView.frame.size.width, 20, CGFloat(trackViewWidth), trackViewHeight) rightActiveOverlay.frame = CGRectMake(thumbView.frame.origin.x + thumbView.frame.size.width, 20, CGFloat(trackViewWidth), trackViewHeight)
rightActiveOverlay.isUserInteractionEnabled = true rightActiveOverlay.isUserInteractionEnabled = true
rightActiveOverlay.layer.cornerRadius = cornerRadius rightActiveOverlay.layer.cornerRadius = cornerRadius
let rightPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.rightLongPressed(_:))) let rightPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.onThumbTouchEnd(_:)))
rightPressRecognizer.minimumPressDuration = 0 rightPressRecognizer.minimumPressDuration = 0
rightActiveOverlay.addGestureRecognizer(rightPressRecognizer) rightActiveOverlay.addGestureRecognizer(rightPressRecognizer)
addSubview(rightActiveOverlay) addSubview(rightActiveOverlay)
@ -198,7 +214,7 @@ open class CarouselScrollbar: View {
thumbView.layer.cornerRadius = cornerRadius thumbView.layer.cornerRadius = cornerRadius
thumbView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action:(#selector(self.handleGesture(_:))))) thumbView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action:(#selector(self.handleGesture(_:)))))
addSubview(thumbView) addSubview(thumbView)
updateActiveOverlayFrames() updateActiveOverlays()
} }
open override func updateView() { open override func updateView() {
@ -223,17 +239,16 @@ open class CarouselScrollbar: View {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Private Methods // MARK: - Private Methods
//-------------------------------------------------- //--------------------------------------------------
func updateThumbViewToLeft() { func onMoveBackward() {
thumbView.frame.origin.x = thumbView.frame.origin.x - CGFloat(actualThumbWidth) thumbView.frame.origin.x = thumbView.frame.origin.x - CGFloat(actualThumbWidth)
updateActiveOverlayFrames() updateActiveOverlays()
} }
func updateThumbViewToRight() { func onMoveForward() {
thumbView.frame.origin.x = thumbView.frame.origin.x + CGFloat(actualThumbWidth) thumbView.frame.origin.x = thumbView.frame.origin.x + CGFloat(actualThumbWidth)
updateActiveOverlayFrames() updateActiveOverlays()
} }
//TO DO: Drag functionality pending
@objc func handleGesture(_ sender: UIPanGestureRecognizer) { @objc func handleGesture(_ sender: UIPanGestureRecognizer) {
switch sender.state { switch sender.state {
@ -254,7 +269,7 @@ open class CarouselScrollbar: View {
} }
} }
@objc func leftLongPressed(_ 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)
leftActiveOverlay.layer.opacity = activeOpacity leftActiveOverlay.layer.opacity = activeOpacity
@ -265,12 +280,12 @@ open class CarouselScrollbar: View {
leftActiveOverlay.backgroundColor = .clear leftActiveOverlay.backgroundColor = .clear
leftActiveOverlay.layer.opacity = defaultOpacity leftActiveOverlay.layer.opacity = defaultOpacity
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { [weak self] in DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { [weak self] in
self?.updateThumbViewToLeft() self?.onMoveBackward()
} }
} }
} }
@objc func rightLongPressed(_ 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)
rightActiveOverlay.layer.opacity = activeOpacity rightActiveOverlay.layer.opacity = activeOpacity
@ -281,21 +296,22 @@ open class CarouselScrollbar: View {
rightActiveOverlay.backgroundColor = .clear rightActiveOverlay.backgroundColor = .clear
rightActiveOverlay.layer.opacity = defaultOpacity rightActiveOverlay.layer.opacity = defaultOpacity
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { [weak self] in DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { [weak self] in
self?.updateThumbViewToRight() self?.onMoveForward()
} }
} }
} }
private func setThumbWidth() { private func setThumbWidth() {
let width = Float (trackViewWidth / (numberOfSlides ?? 1) * _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
thumbWidth = (width <= Float(trackViewWidth) && width > minThumbWidth) ? width : ((width > Float(trackViewWidth)) ? Float(trackViewWidth) : minThumbWidth) thumbWidth = (width <= Float(trackViewWidth) && width > minThumbWidth) ? width : ((width > Float(trackViewWidth)) ? Float(trackViewWidth) : minThumbWidth)
thumbView.frame.size.width = CGFloat(thumbWidth) thumbView.frame.size.width = CGFloat(thumbWidth)
thumbView.frame.origin.x = trackView.frame.origin.x thumbView.frame.origin.x = trackView.frame.origin.x
updateActiveOverlayFrames() checkPositions()
updateActiveOverlays()
} }
private func updateActiveOverlayFrames() { 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
let trackPosition = trackView.frame.origin.x + trackView.frame.size.width let trackPosition = trackView.frame.origin.x + trackView.frame.size.width
@ -312,6 +328,15 @@ open class CarouselScrollbar: View {
rightActiveOverlay.frame.origin.x = thumbView.frame.origin.x + thumbView.frame.size.width - cornerRadius rightActiveOverlay.frame.origin.x = thumbView.frame.origin.x + thumbView.frame.size.width - cornerRadius
rightActiveOverlay.frame.size.width = (trackView.frame.origin.x + trackView.frame.size.width) - (thumbView.frame.origin.x + thumbView.frame.size.width) + cornerRadius rightActiveOverlay.frame.size.width = (trackView.frame.origin.x + trackView.frame.size.width) - (thumbView.frame.origin.x + thumbView.frame.size.width) + cornerRadius
} }
private func checkPositions() {
totalPositions = Int (ceil (Double(numberOfSlides ?? 1) / Double(_selectedLayout.value)))
}
private func setThumb(_ position: Int?) {
thumbView.frame.origin.x = CGFloat(Float((position ?? 1) - 1) * actualThumbWidth) + trackView.frame.origin.x
updateActiveOverlays()
}
} }