Skip to content

Commit a71009f

Browse files
committed
add labelsFixed
1 parent 2b1e915 commit a71009f

File tree

5 files changed

+78
-35
lines changed

5 files changed

+78
-35
lines changed

Demo/RangeSeekSliderDemo/Base.lproj/Main.storyboard

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
<viewControllerLayoutGuide type="bottom" id="FIB-kF-Y0q"/>
1818
</layoutGuides>
1919
<view key="view" contentMode="scaleToFill" id="dDy-w5-TsV">
20-
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
20+
<rect key="frame" x="0.0" y="0.0" width="375" height="817"/>
2121
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
2222
<subviews>
2323
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wcl-zp-wAu">
24-
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
24+
<rect key="frame" x="0.0" y="0.0" width="375" height="817"/>
2525
<subviews>
2626
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Standard Range:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="C9a-jS-yyk">
2727
<rect key="frame" x="16" y="20" width="128" height="21"/>
@@ -154,18 +154,6 @@
154154
</constraints>
155155
<userDefinedRuntimeAttributes>
156156
<userDefinedRuntimeAttribute type="boolean" keyPath="hideLabels" value="YES"/>
157-
<userDefinedRuntimeAttribute type="number" keyPath="minValue">
158-
<real key="value" value="0.0"/>
159-
</userDefinedRuntimeAttribute>
160-
<userDefinedRuntimeAttribute type="number" keyPath="maxValue">
161-
<real key="value" value="100"/>
162-
</userDefinedRuntimeAttribute>
163-
<userDefinedRuntimeAttribute type="number" keyPath="selectedMinValue">
164-
<real key="value" value="0.0"/>
165-
</userDefinedRuntimeAttribute>
166-
<userDefinedRuntimeAttribute type="number" keyPath="selectedMaxValue">
167-
<real key="value" value="100"/>
168-
</userDefinedRuntimeAttribute>
169157
</userDefinedRuntimeAttributes>
170158
</view>
171159
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Custom Label String:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qwj-Dy-ogm">
@@ -176,7 +164,7 @@
176164
</label>
177165
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gdz-ut-dL8" customClass="RangeSeekSlider" customModule="RangeSeekSlider">
178166
<rect key="frame" x="16" y="631" width="343" height="65"/>
179-
<color key="tintColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
167+
<color key="tintColor" red="0.80392158030000005" green="0.80392158030000005" blue="0.80392158030000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
180168
<constraints>
181169
<constraint firstAttribute="height" constant="65" id="wa9-1w-B3f"/>
182170
</constraints>
@@ -187,18 +175,34 @@
187175
<userDefinedRuntimeAttribute type="number" keyPath="minDistance">
188176
<real key="value" value="1"/>
189177
</userDefinedRuntimeAttribute>
190-
<userDefinedRuntimeAttribute type="number" keyPath="selectedMaxValue">
191-
<real key="value" value="67"/>
178+
<userDefinedRuntimeAttribute type="boolean" keyPath="labelsFixed" value="YES"/>
179+
<userDefinedRuntimeAttribute type="color" keyPath="initialColor">
180+
<color key="value" red="0.80392158030000005" green="0.80392158030000005" blue="0.80392158030000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
192181
</userDefinedRuntimeAttribute>
193-
<userDefinedRuntimeAttribute type="number" keyPath="selectedMinValue">
194-
<real key="value" value="0.0"/>
182+
<userDefinedRuntimeAttribute type="color" keyPath="colorBetweenHandles">
183+
<color key="value" red="0.94509803920000002" green="0.32156862749999998" blue="0.63921568630000003" alpha="1" colorSpace="calibratedRGB"/>
184+
</userDefinedRuntimeAttribute>
185+
<userDefinedRuntimeAttribute type="color" keyPath="handleColor">
186+
<color key="value" red="0.94509803920000002" green="0.32156862749999998" blue="0.63921568630000003" alpha="1" colorSpace="calibratedRGB"/>
187+
</userDefinedRuntimeAttribute>
188+
<userDefinedRuntimeAttribute type="color" keyPath="minLabelColor">
189+
<color key="value" red="0.94509803920000002" green="0.32156862749999998" blue="0.63921568630000003" alpha="1" colorSpace="calibratedRGB"/>
190+
</userDefinedRuntimeAttribute>
191+
<userDefinedRuntimeAttribute type="color" keyPath="maxLabelColor">
192+
<color key="value" red="0.94509803920000002" green="0.32156862749999998" blue="0.63921568630000003" alpha="1" colorSpace="calibratedRGB"/>
195193
</userDefinedRuntimeAttribute>
196194
<userDefinedRuntimeAttribute type="number" keyPath="minValue">
197195
<real key="value" value="0.0"/>
198196
</userDefinedRuntimeAttribute>
199197
<userDefinedRuntimeAttribute type="number" keyPath="maxValue">
200198
<real key="value" value="67"/>
201199
</userDefinedRuntimeAttribute>
200+
<userDefinedRuntimeAttribute type="number" keyPath="selectedMinValue">
201+
<real key="value" value="0.0"/>
202+
</userDefinedRuntimeAttribute>
203+
<userDefinedRuntimeAttribute type="number" keyPath="selectedMaxValue">
204+
<real key="value" value="67"/>
205+
</userDefinedRuntimeAttribute>
202206
</userDefinedRuntimeAttributes>
203207
</view>
204208
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="By WorldDownTown" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="l8Q-0R-HSN">
@@ -255,6 +259,8 @@
255259
</constraints>
256260
</view>
257261
<navigationItem key="navigationItem" title="RangeSeekSlider" id="BuP-se-RZI"/>
262+
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
263+
<size key="freeformSize" width="375" height="817"/>
258264
<connections>
259265
<outlet property="rangeSlider" destination="evq-sI-chw" id="k72-tE-yA5"/>
260266
<outlet property="rangeSliderCurrency" destination="aHO-Yd-TsS" id="hMn-Ta-0mN"/>

Demo/RangeSeekSliderDemo/ViewController.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ final class ViewController: UIViewController {
8080
rangeSliderCustomString.tintColor = #colorLiteral(red: 0.8666666667, green: 0.8666666667, blue: 0.8666666667, alpha: 1)
8181
rangeSliderCustomString.numberFormatter.locale = Locale.current
8282
rangeSliderCustomString.numberFormatter.numberStyle = .currency
83+
rangeSliderCustomString.labelsFixed = true
8384
rangeSliderCustomString.initialColor = #colorLiteral(red: 0.8666666667, green: 0.8666666667, blue: 0.8666666667, alpha: 1)
8485
}
8586

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ The font of the maximum value text label. If not set, the default is system font
6868
Each handle in the slider has a label above it showing the current selected value. If you change number format, update each properties of `NumberFormatter`. By default, this is displayed as a decimal format.
6969

7070
#### `hideLabels`
71-
When set to `true` the labels above the slider controls will be hidden. Default is false.
71+
When set to `true` the labels above the slider controls will be hidden. Default is `false`.
72+
73+
#### `labelsFixed`
74+
Fixes the labels above the slider controls. If `true`, labels will be fixed to both ends. Otherwise labels will move with the handles. Default is `false`.
7275

7376
#### `minDistance`
7477
The minimum distance the two selected slider values must be apart. Default is `0.0`.
@@ -95,15 +98,15 @@ If set it will update the color of the handle borders. Default is `tintColor`.
9598
The color of the entire slider when the handle is set to the minimum value and the maximum value. Default is nil.
9699

97100
#### `disableRange`
98-
If true, the control will mimic a normal slider and have only one handle rather than a range.
101+
If `true`, the control will mimic a normal slider and have only one handle rather than a range.
99102

100103
In this case, the selectedMinValue will be not functional anymore. Use selectedMaxValue instead to determine the value the user has selected.
101104

102105
#### `enableStep`
103-
If true the control will snap to point at each `step` (property) between minValue and maxValue. Default value is disabled.
106+
If `true` the control will snap to point at each `step` (property) between minValue and maxValue. Default value is disabled.
104107

105108
#### `step`
106-
If `enableStep` is true, this controls the value of each step. E.g. if this value is 20, the control will snap to values 20,40,60...etc. Set this is you enable the `enableStep` property.
109+
If `enableStep` is `true`, this controls the value of each step. E.g. if this value is 20, the control will snap to values 20,40,60...etc. Set this is you enable the `enableStep` property.
107110

108111
#### `handleImage`
109112
If set the image passed will be used for the handles.

RangeSeekSlider.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'RangeSeekSlider'
3-
s.version = '1.3.0'
3+
s.version = '1.4.0'
44
s.summary = 'RangeSeedSlider provides a customizable range slider like a UISlider.'
55
s.description = <<-DESC
66
RangeSeedSlider provides a customizable range slider like a UISlider.

Sources/RangeSeekSlider.swift

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,18 @@ import UIKit
3434
public weak var delegate: RangeSeekSliderDelegate?
3535

3636
/// The minimum possible value to select in the range
37-
@IBInspectable public var minValue: CGFloat = 0.0
37+
@IBInspectable public var minValue: CGFloat = 0.0 {
38+
didSet {
39+
refresh()
40+
}
41+
}
3842

3943
/// The maximum possible value to select in the range
40-
@IBInspectable public var maxValue: CGFloat = 100.0
44+
@IBInspectable public var maxValue: CGFloat = 100.0 {
45+
didSet {
46+
refresh()
47+
}
48+
}
4149

4250
/// The preselected minumum value
4351
/// (note: This should be less than the selectedMaxValue)
@@ -85,7 +93,15 @@ import UIKit
8593
}()
8694

8795
/// Hides the labels above the slider controls. true = labels will be hidden. false = labels will be shown. Default is false.
88-
@IBInspectable public var hideLabels: Bool = false
96+
@IBInspectable public var hideLabels: Bool = false {
97+
didSet {
98+
minLabel.isHidden = hideLabels
99+
maxLabel.isHidden = hideLabels
100+
}
101+
}
102+
103+
/// fixes the labels above the slider controls. true: labels will be fixed to both ends. false: labels will move with the handles. Default is false.
104+
@IBInspectable public var labelsFixed: Bool = false
89105

90106
/// The minimum distance the two selected slider values must be apart. Default is 0.
91107
@IBInspectable public var minDistance: CGFloat = 0.0 {
@@ -437,11 +453,8 @@ import UIKit
437453
}
438454

439455
private func updateLabelValues() {
440-
if hideLabels {
441-
minLabel.string = nil
442-
maxLabel.string = nil
443-
return
444-
}
456+
minLabel.isHidden = hideLabels
457+
maxLabel.isHidden = hideLabels
445458

446459
if let replacedString = delegate?.rangeSeekSlider(self, stringForMinValue: selectedMinValue) {
447460
minLabel.string = replacedString
@@ -517,6 +530,15 @@ import UIKit
517530

518531
private func updateLabelPositions() {
519532
// the center points for the labels are X = the same x position as the relevant handle. Y = the y position of the handle minus half the height of the text label, minus some padding.
533+
534+
minLabel.frame.size = minLabelTextSize
535+
maxLabel.frame.size = maxLabelTextSize
536+
537+
if labelsFixed {
538+
updateFixedLabelPositions()
539+
return
540+
}
541+
520542
let minSpacingBetweenLabels: CGFloat = 8.0
521543

522544
let newMinLabelCenter: CGPoint = CGPoint(x: leftHandle.frame.midX,
@@ -525,9 +547,6 @@ import UIKit
525547
let newMaxLabelCenter: CGPoint = CGPoint(x: rightHandle.frame.midX,
526548
y: rightHandle.frame.minY - (maxLabelTextSize.height / 2.0) - labelPadding)
527549

528-
minLabel.frame.size = minLabelTextSize
529-
maxLabel.frame.size = maxLabelTextSize
530-
531550
let newLeftMostXInMaxLabel: CGFloat = newMaxLabelCenter.x - maxLabelTextSize.width / 2.0
532551
let newRightMostXInMinLabel: CGFloat = newMinLabelCenter.x + minLabelTextSize.width / 2.0
533552
let newSpacingBetweenTextLabels: CGFloat = newLeftMostXInMaxLabel - newRightMostXInMinLabel
@@ -566,6 +585,20 @@ import UIKit
566585
}
567586
}
568587

588+
private func updateFixedLabelPositions() {
589+
minLabel.position = CGPoint(x: xPositionAlongLine(for: minValue),
590+
y: sliderLine.frame.minY - (minLabelTextSize.height / 2.0) - (handleDiameter / 2.0) - labelPadding)
591+
maxLabel.position = CGPoint(x: xPositionAlongLine(for: maxValue),
592+
y: sliderLine.frame.minY - (maxLabelTextSize.height / 2.0) - (handleDiameter / 2.0) - labelPadding)
593+
if minLabel.frame.minX < 0.0 {
594+
minLabel.frame.origin.x = 0.0
595+
}
596+
597+
if maxLabel.frame.maxX > frame.width {
598+
maxLabel.frame.origin.x = frame.width - maxLabel.frame.width
599+
}
600+
}
601+
569602
fileprivate func refresh() {
570603
if enableStep && step > 0.0 {
571604
selectedMinValue = CGFloat(roundf(Float(selectedMinValue / step))) * step

0 commit comments

Comments
 (0)