Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature to track position of the IndicatorView #160

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 49 additions & 6 deletions Pod/Classes/BetterSegmentedControl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

import UIKit

public protocol BetterSegmentedControlDelegate {
func didMoveIndicator(to percent: Double, animated: Bool)
}

@IBDesignable open class BetterSegmentedControl: UIControl {
private struct Constants {
static let minimumIntrinsicContentSizeHeight: CGFloat = 32.0
Expand All @@ -31,6 +35,17 @@ import UIKit
}
}

public var delegate: BetterSegmentedControlDelegate?

/// Whether the control should track the position of the IndicatorView. Cannot be enabled if panning is disabled. Defaults to `false`.
@IBInspectable public var trackIndicatorPosition: Bool = false {
didSet {
if panningDisabled {
trackIndicatorPosition = false
}
}
}

/// The currently selected index indicator view.
public let indicatorView = IndicatorView()

Expand All @@ -41,7 +56,11 @@ import UIKit
@IBInspectable public var announcesValueImmediately: Bool = true

/// Whether the the control should ignore pan gestures. Defaults to `false`.
@IBInspectable public var panningDisabled: Bool = false
@IBInspectable public var panningDisabled: Bool = false {
didSet {
trackIndicatorPosition = !panningDisabled
}
}

/// The control's and indicator's corner radii.
@IBInspectable public var cornerRadius: CGFloat {
Expand Down Expand Up @@ -476,17 +495,41 @@ import UIKit
setIndex(closestIndex(toPoint: location), shouldSendValueChangedEvent: true)
}

@objc private func panned(_ gestureRecognizer: UIPanGestureRecognizer!) {
@objc private func panned(_ gestureRecognizer: UIPanGestureRecognizer!) {

let trackingLaneFrame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: (self.bounds.width - indicatorView.frame.width) - indicatorViewInset, height: self.bounds.height)

switch gestureRecognizer.state {
case .began:
initialIndicatorViewFrame = indicatorView.frame
case .changed:
var frame = initialIndicatorViewFrame!
frame.origin.x += gestureRecognizer.translation(in: self).x
frame.origin.x = max(min(frame.origin.x, bounds.width - indicatorViewInset - frame.width), indicatorViewInset)
indicatorView.frame = frame
var indicatorFrame = initialIndicatorViewFrame!
indicatorFrame.origin.x += gestureRecognizer.translation(in: self).x
indicatorFrame.origin.x = max(min(indicatorFrame.origin.x, bounds.width - indicatorViewInset - indicatorFrame.width), indicatorViewInset)

if trackIndicatorPosition
{
let frameX = indicatorFrame.origin.x == 5 ? 0 : indicatorFrame.origin.x
let percent = frameX / trackingLaneFrame.width

delegate?.didMoveIndicator(to: Double(percent), animated: false)
}

indicatorView.frame = indicatorFrame

case .ended, .failed, .cancelled:
setIndex(closestIndex(toPoint: indicatorView.center), shouldSendValueChangedEvent: true)

if trackIndicatorPosition
{
let indicatorFrame = indicatorView.frame

let frameX = indicatorFrame.origin.x == 5 ? 0 : indicatorFrame.origin.x
let percent = frameX / trackingLaneFrame.width

delegate?.didMoveIndicator(to: Double(percent), animated: true)
}

default: break
}
}
Expand Down