diff --git a/VDS/Components/CarouselScrollbar/CarouselScrollbar.swift b/VDS/Components/CarouselScrollbar/CarouselScrollbar.swift index a0523342..918c4864 100644 --- a/VDS/Components/CarouselScrollbar/CarouselScrollbar.swift +++ b/VDS/Components/CarouselScrollbar/CarouselScrollbar.swift @@ -104,16 +104,18 @@ open class CarouselScrollbar: View { //-------------------------------------------------- // Sizes are from InVision design specs. internal var containerSize: CGSize { CGSize(width: 45, height: 44) } - + internal var _selectedLayout: Layout = .oneUP + internal var _numberOfSlides: Int? = 1 + internal var heightConstraint: NSLayoutConstraint? + private let trackViewWidth = 96 private let trackViewHeight: CGFloat = 4 private let minThumbWidth: Float = 16.0 private var thumbWidth: Float = 16.0 private var actualThumbWidth: Float = 0.0 - private var _selectedLayout: Layout = .oneUP - private var _numberOfSlides: Int? = 1 - internal var cornerRadius: CGFloat = 4.0 - internal var heightConstraint: NSLayoutConstraint? + private let cornerRadius: CGFloat = 4.0 + private let activeOpacity: Float = 0.15 + private let defaultOpacity: Float = 1 /// Track view with fixed width internal var trackView: UIView = { @@ -172,19 +174,23 @@ open class CarouselScrollbar: View { trackView.frame = CGRectMake(20, 20, CGFloat(trackViewWidth), trackViewHeight) trackView.layer.cornerRadius = cornerRadius addSubview(trackView) - + ///Left active overlay leftActiveOverlay.frame = CGRectMake(trackView.frame.origin.x, 20, CGFloat(trackViewWidth), trackViewHeight) - leftActiveOverlay.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))) leftActiveOverlay.isUserInteractionEnabled = true leftActiveOverlay.layer.cornerRadius = cornerRadius + let leftPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.leftLongPressed(_:))) + leftPressRecognizer.minimumPressDuration = 0 + leftActiveOverlay.addGestureRecognizer(leftPressRecognizer) addSubview(leftActiveOverlay) ///Right active overlay rightActiveOverlay.frame = CGRectMake(thumbView.frame.origin.x + thumbView.frame.size.width, 20, CGFloat(trackViewWidth), trackViewHeight) - rightActiveOverlay.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))) rightActiveOverlay.isUserInteractionEnabled = true rightActiveOverlay.layer.cornerRadius = cornerRadius + let rightPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.rightLongPressed(_:))) + rightPressRecognizer.minimumPressDuration = 0 + rightActiveOverlay.addGestureRecognizer(rightPressRecognizer) addSubview(rightActiveOverlay) //Thumbview @@ -192,7 +198,7 @@ open class CarouselScrollbar: View { thumbView.layer.cornerRadius = cornerRadius thumbView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action:(#selector(self.handleGesture(_:))))) addSubview(thumbView) - updateFrames() + updateActiveOverlayFrames() } open override func updateView() { @@ -217,21 +223,17 @@ open class CarouselScrollbar: View { //-------------------------------------------------- // MARK: - Private Methods //-------------------------------------------------- - @objc func handleTap(_ gestureRecognizer: UITapGestureRecognizer) { - // handling code - let tag = gestureRecognizer.view?.tag - switch tag! { - case 2 : - thumbView.frame.origin.x = thumbView.frame.origin.x - CGFloat(actualThumbWidth) - updateFrames() - case 3 : - thumbView.frame.origin.x = thumbView.frame.origin.x + CGFloat(actualThumbWidth) - updateFrames() - default: - print("default") - } + func updateThumbViewToLeft() { + thumbView.frame.origin.x = thumbView.frame.origin.x - CGFloat(actualThumbWidth) + updateActiveOverlayFrames() } + func updateThumbViewToRight() { + thumbView.frame.origin.x = thumbView.frame.origin.x + CGFloat(actualThumbWidth) + updateActiveOverlayFrames() + } + + //TO DO: Drag functionality pending @objc func handleGesture(_ sender: UIPanGestureRecognizer) { switch sender.state { @@ -252,24 +254,64 @@ open class CarouselScrollbar: View { } } + @objc func leftLongPressed(_ gesture: UILongPressGestureRecognizer) { + if gesture.state == .began { + leftActiveOverlay.backgroundColor = activeOverlayColorConfiguration.getColor(self) + leftActiveOverlay.layer.opacity = activeOpacity + } else if gesture.state == .cancelled { + leftActiveOverlay.backgroundColor = .clear + leftActiveOverlay.layer.opacity = defaultOpacity + } else if gesture.state == .ended { + leftActiveOverlay.backgroundColor = .clear + leftActiveOverlay.layer.opacity = defaultOpacity + DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { [weak self] in + self?.updateThumbViewToLeft() + } + } + } + + @objc func rightLongPressed(_ gesture: UILongPressGestureRecognizer) { + if gesture.state == .began { + rightActiveOverlay.backgroundColor = activeOverlayColorConfiguration.getColor(self) + rightActiveOverlay.layer.opacity = activeOpacity + } else if gesture.state == .cancelled { + rightActiveOverlay.backgroundColor = .clear + rightActiveOverlay.layer.opacity = defaultOpacity + } else if gesture.state == .ended { + rightActiveOverlay.backgroundColor = .clear + rightActiveOverlay.layer.opacity = defaultOpacity + DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { [weak self] in + self?.updateThumbViewToRight() + } + } + } + private func setThumbWidth() { let width = Float (trackViewWidth / (numberOfSlides ?? 1) * _selectedLayout.value) 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.origin.x = trackView.frame.origin.x - updateFrames() + updateActiveOverlayFrames() } - private func updateFrames() { - //left active overlay origin - x, width - leftActiveOverlay.frame.size.width = thumbView.frame.origin.x - trackView.frame.origin.x + private func updateActiveOverlayFrames() { + // adjusting thumb position if it goes beyond trackView. + let thumbPosition = thumbView.frame.origin.x + thumbView.frame.size.width + let trackPosition = trackView.frame.origin.x + trackView.frame.size.width + if thumbPosition > trackPosition { + thumbView.frame.origin.x = trackPosition - thumbView.frame.size.width + } else if thumbView.frame.origin.x < trackView.frame.origin.x { + thumbView.frame.origin.x = trackView.frame.origin.x + } - //right active overlay origin - x, width - let position1 = thumbView.frame.origin.x + thumbView.frame.size.width - let position2 = trackView.frame.origin.x + trackView.frame.size.width - rightActiveOverlay.frame.origin.x = position1 - rightActiveOverlay.frame.size.width = position2 - position1 + //left active overlay position update + leftActiveOverlay.frame.size.width = thumbView.frame.origin.x - trackView.frame.origin.x + cornerRadius + + //left active overlay position update + 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 } } +