Apple Fitness workout fixer + Strava uploader
1import SwiftUI
2
3struct RangeSliderView: View {
4 @Binding var lowerBound: Double
5 @Binding var upperBound: Double
6
7 private let thumbSize: CGFloat = 24
8 private let trackHeight: CGFloat = 6
9 private let minimumGap: Double = 0.02
10
11 var body: some View {
12 GeometryReader { geometry in
13 let width = geometry.size.width - thumbSize
14 ZStack(alignment: .leading) {
15 // Background track
16 Capsule()
17 .fill(Color(UIColor.systemGray4))
18 .frame(height: trackHeight)
19 .padding(.horizontal, thumbSize / 2)
20
21 // Selected range
22 Capsule()
23 .fill(Color.accentColor)
24 .frame(
25 width: CGFloat(upperBound - lowerBound) * width,
26 height: trackHeight
27 )
28 .offset(x: thumbSize / 2 + CGFloat(lowerBound) * width)
29
30 // Lower thumb
31 thumb()
32 .offset(x: CGFloat(lowerBound) * width)
33 .gesture(
34 DragGesture()
35 .onChanged { value in
36 let new = Double(value.location.x / width)
37 lowerBound = min(max(new, 0), upperBound - minimumGap)
38 }
39 )
40
41 // Upper thumb
42 thumb()
43 .offset(x: CGFloat(upperBound) * width)
44 .gesture(
45 DragGesture()
46 .onChanged { value in
47 let new = Double(value.location.x / width)
48 upperBound = max(min(new, 1), lowerBound + minimumGap)
49 }
50 )
51 }
52 .frame(height: 44)
53 }
54 .frame(height: 44)
55 }
56
57 private func thumb() -> some View {
58 Circle()
59 .fill(.white)
60 .shadow(color: .black.opacity(0.15), radius: 3, y: 1)
61 .frame(width: thumbSize, height: thumbSize)
62 .contentShape(Rectangle().size(width: 44, height: 44))
63 }
64}