@@ -39,14 +39,14 @@ import SwiftUI
39
39
///
40
40
/// You can also use a step parameter to provide incremental steps along the path of the slider. For example,
41
41
/// if you have a slider with a range of 0 to 100, and you set the step value to 5, the slider’s increments would be 0, 5, 10, and so on.
42
- public struct RangeSlider : View {
42
+ public struct RangeSlider < V : BinaryFloatingPoint > : View {
43
43
// MARK: - Properties
44
-
44
+
45
45
/// The value of thumb on the left-hand-side.
46
- @Binding var lowValue : Double
46
+ @Binding var lowValue : V
47
47
48
48
/// The value of thumb on the right-hand-side.
49
- @Binding var highValue : Double
49
+ @Binding var highValue : V
50
50
51
51
/// The zIndex for the thumb on the right-hand-side.
52
52
@State private var zIndexRHS : Double = 0
@@ -67,16 +67,16 @@ public struct RangeSlider: View {
67
67
let displayBounds : ClosedRange < Double > ?
68
68
69
69
/// The lower-bound for the slider.
70
- let minimumValue : Double
70
+ let minimumValue : V
71
71
72
72
/// The upper-bound for the slider.
73
- let maximumValue : Double
73
+ let maximumValue : V
74
74
75
75
/// The distance between the upper and lower bounds.
76
- let totalDistance : Double
76
+ let totalDistance : V
77
77
78
78
/// The distance between each value. Defaults to zero.
79
- let step : Double ?
79
+ let step : V ?
80
80
81
81
/// Whether or not to display the low and high slider values.
82
82
let showValues : Bool
@@ -92,10 +92,10 @@ public struct RangeSlider: View {
92
92
93
93
/// The width of the sliders track.
94
94
let lineWidth : CGFloat
95
-
95
+
96
96
/// A callback for when editing begins and ends.
97
97
let onEditingChanged : ( Bool ) -> Void
98
-
98
+
99
99
public var body : some View {
100
100
VStack {
101
101
if title != nil {
@@ -182,7 +182,6 @@ public struct RangeSlider: View {
182
182
}
183
183
184
184
// MARK: - Methods
185
-
186
185
/// Creates a slider to select two values from a given range.
187
186
///
188
187
/// The values of the created instance are equal to the position of the given values within bounds, mapped into 0...1.
@@ -195,11 +194,11 @@ public struct RangeSlider: View {
195
194
/// - Parameter onEditingChanged: A callback for when editing begins and ends.
196
195
public init (
197
196
_ title: String ? = nil ,
198
- lowValue: Binding < Double > ,
199
- highValue: Binding < Double > ,
197
+ lowValue: Binding < V > ,
198
+ highValue: Binding < V > ,
200
199
in bounds: ClosedRange < Double > ,
201
200
displayBounds: ClosedRange < Double > ? = nil ,
202
- step: Double ? = nil ,
201
+ step: V ? = nil ,
203
202
showValues: Bool = true ,
204
203
showDifferenceOnEditing: Bool = false ,
205
204
color: Color = . blue,
@@ -208,8 +207,8 @@ public struct RangeSlider: View {
208
207
onEditingChanged: @escaping ( Bool ) -> Void ) {
209
208
_lowValue = lowValue
210
209
_highValue = highValue
211
- minimumValue = bounds. lowerBound
212
- maximumValue = bounds. upperBound
210
+ minimumValue = V ( bounds. lowerBound)
211
+ maximumValue = V ( bounds. upperBound)
213
212
totalDistance = maximumValue - minimumValue
214
213
_displayTitle = State ( initialValue: title ?? " " )
215
214
self . title = showDifferenceOnEditing && title == nil ? " " : title
@@ -224,18 +223,18 @@ public struct RangeSlider: View {
224
223
self . onEditingChanged = onEditingChanged
225
224
}
226
225
227
- private func scale( _ value: Double , translate: Bool = false ) -> CGFloat {
226
+ private func scale( _ value: V , translate: Bool = false ) -> V {
228
227
guard let display = displayBounds else { return value }
229
228
230
- let normal = value / ( bounds . upperBound - bounds . lowerBound )
229
+ let normal = value / ( maximumValue - minimumValue )
231
230
232
- return normal * ( display. upperBound - display. lowerBound)
231
+ return normal * V ( ( display. upperBound - display. lowerBound) )
233
232
}
234
233
235
- private func translate( _ value: Double ) -> CGFloat {
236
- guard let display = displayBounds else { return value }
234
+ private func translate( _ value: V ) -> Double {
235
+ guard let display = displayBounds else { return Double ( value) }
237
236
238
- return value + display. lowerBound - bounds. lowerBound
237
+ return Double ( value) + display. lowerBound - bounds. lowerBound
239
238
}
240
239
241
240
private func dragGesture( side: Thumb . Side , geo: GeometryProxy ) -> some Gesture {
@@ -254,7 +253,7 @@ public struct RangeSlider: View {
254
253
}
255
254
256
255
if showDifferenceOnEditing {
257
- displayTitle = String ( format: " %0.2f " , scale ( highValue - lowValue) )
256
+ displayTitle = String ( format: " %0.2f " , Double ( scale ( highValue - lowValue) ) )
258
257
}
259
258
}
260
259
. onEnded { _ in
@@ -275,16 +274,16 @@ public struct RangeSlider: View {
275
274
}
276
275
}
277
276
278
- private func getNewValue( for side: Thumb . Side , _ translationX: CGFloat , _ geo: GeometryProxy ) -> Double ? {
277
+ private func getNewValue( for side: Thumb . Side , _ translationX: CGFloat , _ geo: GeometryProxy ) -> V ? {
279
278
if startX == nil {
280
279
startX = xPosition ( side: side, geo)
281
280
onEditingChanged ( true )
282
281
}
283
282
284
283
guard let startX = startX else { return nil }
285
284
286
- var newValue : Double {
287
- var value = Double ( ( startX + translationX) / geo. size. width) * totalDistance
285
+ var newValue : V {
286
+ var value = V ( ( startX + translationX) / geo. size. width) * totalDistance
288
287
289
288
if let step = step {
290
289
value = value - value. remainder ( dividingBy: step)
@@ -305,7 +304,6 @@ public struct RangeSlider: View {
305
304
}
306
305
307
306
// MARK: - Components
308
-
309
307
private struct Thumb : View {
310
308
enum Side {
311
309
case lhs
@@ -348,3 +346,4 @@ private struct Track: View {
348
346
. frame ( height: lineWidth)
349
347
}
350
348
}
349
+
0 commit comments