Digital ACT-191 ONEAPP-6830 story: refactored code

This commit is contained in:
vasavk 2024-03-21 21:32:04 +05:30
parent 939465f7bc
commit 9290e40a2a

View File

@ -35,14 +35,10 @@ open class CarouselScrollbar: View {
// MARK: - Public Properties // MARK: - Public Properties
//-------------------------------------------------- //--------------------------------------------------
/// Used to set total number of slides within carousel /// Used to set total number of slides within carousel
open var numberOfSlides: Int? { open var numberOfSlides: Int {
get { return _numberOfSlides } get { return _numberOfSlides }
set { set {
if let newValue { _numberOfSlides = newValue
_numberOfSlides = newValue
} else {
_numberOfSlides = 1
}
setThumbWidth() setThumbWidth()
scrollThumbToPosition(position) scrollThumbToPosition(position)
setNeedsUpdate() setNeedsUpdate()
@ -95,15 +91,11 @@ 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? { open var position: Int {
get { return _position } get { return _position }
set { set {
if let newValue { checkPositions()
checkPositions() _position = (newValue > totalPositions) ? totalPositions : newValue
_position = (newValue > totalPositions ?? 1) ? totalPositions : newValue
} else {
_position = 1
}
scrollThumbToPosition(position) scrollThumbToPosition(position)
setNeedsUpdate() setNeedsUpdate()
} }
@ -121,9 +113,9 @@ open class CarouselScrollbar: View {
// Sizes are from InVision design specs. // Sizes are from InVision design specs.
internal var containerSize: CGSize { CGSize(width: 45, height: 44) } internal var containerSize: CGSize { CGSize(width: 45, height: 44) }
internal var _selectedLayout: Layout = .oneUP internal var _selectedLayout: Layout = .oneUP
internal var _numberOfSlides: Int? = 1 internal var _numberOfSlides: Int = 1
internal var totalPositions: Int? = 1 internal var totalPositions: Int = 1
internal var _position: Int? = 1 internal var _position: Int = 1
internal var trayOriginalCenter: CGPoint! internal var trayOriginalCenter: CGPoint!
private let trackViewWidth = 96 private let trackViewWidth = 96
@ -131,11 +123,13 @@ open class CarouselScrollbar: View {
private let minThumbWidth: Float = 16.0 private let minThumbWidth: Float = 16.0
private var thumbWidth: Float = 16.0 private var thumbWidth: Float = 16.0
private var computedWidth: Float = 0.0 private var computedWidth: Float = 0.0
private let cornerRadius: CGFloat = 4.0 private let cornerRadius: CGFloat = 2.0
private let activeOpacity: Float = 0.15 private let activeOpacity: Float = 0.15
private let defaultOpacity: Float = 1 private let defaultOpacity: Float = 1
internal var containerView = View() internal var containerView = View().with {
$0.clipsToBounds = true
}
internal var trackView = View() internal var trackView = View()
internal var leftActiveOverlay = View() internal var leftActiveOverlay = View()
internal var rightActiveOverlay = View() internal var rightActiveOverlay = View()
@ -182,7 +176,7 @@ open class CarouselScrollbar: View {
leftActiveOverlay.frame = CGRectMake(trackView.frame.origin.x, 0, CGFloat(trackViewWidth), containerSize.height) leftActiveOverlay.frame = CGRectMake(trackView.frame.origin.x, 0, CGFloat(trackViewWidth), containerSize.height)
leftActiveOverlay.isUserInteractionEnabled = true leftActiveOverlay.isUserInteractionEnabled = true
leftActiveOverlay.backgroundColor = .clear leftActiveOverlay.backgroundColor = .clear
let leftPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.onThumbTouchStart(_:))) let leftPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(onLeftViewLongPressRecognizer(_:)))
leftPressRecognizer.minimumPressDuration = 0 leftPressRecognizer.minimumPressDuration = 0
leftActiveOverlay.addGestureRecognizer(leftPressRecognizer) leftActiveOverlay.addGestureRecognizer(leftPressRecognizer)
containerView.addSubview(leftActiveOverlay) containerView.addSubview(leftActiveOverlay)
@ -195,7 +189,7 @@ open class CarouselScrollbar: View {
rightActiveOverlay.frame = CGRectMake(thumbView.frame.origin.x + thumbView.frame.size.width, 0, CGFloat(trackViewWidth), containerSize.height) rightActiveOverlay.frame = CGRectMake(thumbView.frame.origin.x + thumbView.frame.size.width, 0, CGFloat(trackViewWidth), containerSize.height)
rightActiveOverlay.isUserInteractionEnabled = true rightActiveOverlay.isUserInteractionEnabled = true
rightActiveOverlay.backgroundColor = .clear rightActiveOverlay.backgroundColor = .clear
let rightPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.onThumbTouchEnd(_:))) let rightPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(onRightViewLongPressRecognizer(_:)))
rightPressRecognizer.minimumPressDuration = 0 rightPressRecognizer.minimumPressDuration = 0
rightActiveOverlay.addGestureRecognizer(rightPressRecognizer) rightActiveOverlay.addGestureRecognizer(rightPressRecognizer)
containerView.addSubview(rightActiveOverlay) containerView.addSubview(rightActiveOverlay)
@ -207,7 +201,7 @@ open class CarouselScrollbar: View {
//Thumbview //Thumbview
thumbView.frame = CGRectMake(0, 0, CGFloat(thumbWidth), containerSize.height) thumbView.frame = CGRectMake(0, 0, CGFloat(thumbWidth), containerSize.height)
thumbView.backgroundColor = .clear thumbView.backgroundColor = .clear
thumbView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action:(#selector(self.onScrubberDrag(_:))))) thumbView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action:(#selector(onScrubberDrag(_:)))))
containerView.addSubview(thumbView) containerView.addSubview(thumbView)
updateActiveOverlays() updateActiveOverlays()
@ -240,18 +234,18 @@ open class CarouselScrollbar: View {
// MARK: - Private Methods // MARK: - Private Methods
//-------------------------------------------------- //--------------------------------------------------
func onMoveBackward() { func onMoveBackward() {
position = (position ?? 1) - 1 position = position - 1
scrollThumbToPosition(position) scrollThumbToPosition(position)
} }
func onMoveForward() { func onMoveForward() {
position = (position ?? 1) + 1 position = position + 1
scrollThumbToPosition(position) scrollThumbToPosition(position)
} }
// Compute track width and should maintain minimum thumb width if needed // Compute track width and should maintain minimum thumb width if needed
private func setThumbWidth() { private func setThumbWidth() {
let width = (Float(trackViewWidth) / Float(numberOfSlides ?? 1)) * Float(_selectedLayout.value) let width = (Float(trackViewWidth) / Float(numberOfSlides)) * Float(_selectedLayout.value)
computedWidth = (width > Float(trackViewWidth)) ? Float(trackViewWidth) : width computedWidth = (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)
@ -284,12 +278,12 @@ open class CarouselScrollbar: View {
} }
private func checkPositions() { private func checkPositions() {
totalPositions = Int (ceil (Double(numberOfSlides ?? 1) / Double(_selectedLayout.value))) totalPositions = Int (ceil (Double(numberOfSlides) / Double(_selectedLayout.value)))
} }
private func scrollThumbToPosition(_ position: Int?) { private func scrollThumbToPosition(_ position: Int?) {
setThumb(at: position) self.setThumb(at: position)
onScrubberDidChange?(position ?? 1) self.onScrubberDidChange?(position ?? 1)
} }
private func setThumb(at position: Int?) { private func setThumb(at position: Int?) {
@ -310,46 +304,37 @@ open class CarouselScrollbar: View {
trayOriginalCenter = thumbView.center trayOriginalCenter = thumbView.center
} else if sender.state == UIGestureRecognizer.State.changed { } else if sender.state == UIGestureRecognizer.State.changed {
let draggedPositions = Int (ceil (Double(translation.x) / Double(computedWidth))) let draggedPositions = Int (ceil (Double(translation.x) / Double(computedWidth)))
setThumb(at: (position ?? 1) + draggedPositions) setThumb(at: position + 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 draggedPositions = Int (ceil (Double(translation.x) / Double(computedWidth))) let draggedPositions = Int (ceil (Double(translation.x) / Double(computedWidth)))
position = (((position ?? 1) + draggedPositions) < 1) ? 1 : ((position ?? 1) + draggedPositions) position = ((position + draggedPositions) < 1) ? 1 : (position + draggedPositions)
} }
} }
// Move the scrollbar thumb to the left while tapping on the left side of the scrubber. // Move the scrollbar thumb to the left while tapping on the left side of the scrubber.
@objc func onThumbTouchStart(_ gesture: UILongPressGestureRecognizer) { @objc func onLeftViewLongPressRecognizer(_ gesture: UILongPressGestureRecognizer) {
UIView.animate(withDuration: 0.1, delay: 0.0, options: .curveLinear, animations: { [self] in animateOverlay(layer: leftActiveOverlayLayer, with: gesture, onGestureEnd: onMoveBackward)
if gesture.state == .began {
leftActiveOverlayLayer.backgroundColor = activeOverlayColorConfiguration.getColor(self).cgColor
leftActiveOverlayLayer.opacity = activeOpacity
} else if gesture.state == .cancelled {
leftActiveOverlayLayer.backgroundColor = UIColor.clear.cgColor
leftActiveOverlayLayer.opacity = defaultOpacity
} else if gesture.state == .ended {
leftActiveOverlayLayer.backgroundColor = UIColor.clear.cgColor
leftActiveOverlayLayer.opacity = defaultOpacity
UIView.performWithoutAnimation {
self.onMoveBackward()
}
}
})
} }
// Move the scrollbar thumb to the right while tapping on the right side of the scrubber. // Move the scrollbar thumb to the right while tapping on the right side of the scrubber.
@objc func onThumbTouchEnd(_ gesture: UILongPressGestureRecognizer) { @objc func onRightViewLongPressRecognizer(_ gesture: UILongPressGestureRecognizer) {
UIView.animate(withDuration: 0.1, delay: 0.0, options: .curveLinear, animations: { [self] in animateOverlay(layer: rightActiveOverlayLayer, with: gesture, onGestureEnd: onMoveForward)
}
private func animateOverlay(layer: CALayer, with gesture: UILongPressGestureRecognizer, onGestureEnd: @escaping(() -> Void)) {
UIView.animate(withDuration: 0.1, delay: 0.0, options: .curveLinear, animations: { [weak self] in
guard let self else { return }
if gesture.state == .began { if gesture.state == .began {
rightActiveOverlayLayer.backgroundColor = activeOverlayColorConfiguration.getColor(self).cgColor layer.backgroundColor = activeOverlayColorConfiguration.getColor(self).cgColor
rightActiveOverlayLayer.opacity = activeOpacity layer.opacity = activeOpacity
} else if gesture.state == .cancelled { } else if gesture.state == .cancelled {
rightActiveOverlayLayer.backgroundColor = UIColor.clear.cgColor layer.backgroundColor = UIColor.clear.cgColor
rightActiveOverlayLayer.opacity = defaultOpacity layer.opacity = defaultOpacity
} else if gesture.state == .ended { } else if gesture.state == .ended {
rightActiveOverlayLayer.backgroundColor = UIColor.clear.cgColor layer.backgroundColor = UIColor.clear.cgColor
rightActiveOverlayLayer.opacity = defaultOpacity layer.opacity = defaultOpacity
self.onMoveForward() onGestureEnd()
} }
}) })
} }