Digital ACT-191 ONEAPP-6830 story: refactored code
This commit is contained in:
parent
939465f7bc
commit
9290e40a2a
@ -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()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user