From f6195f39c8f5cf31315f085f3c571c60f1eb4fb1 Mon Sep 17 00:00:00 2001 From: tomosaaan Date: Fri, 25 Oct 2024 18:53:39 +0900 Subject: [PATCH] feat: follow selected position to latest drag position --- Example/Example/ContentView.swift | 10 +--------- .../GraphRangeSlider/Extensions/Array+.swift | 7 +++++++ Sources/GraphRangeSlider/GraphRangeSlider.swift | 2 +- Sources/GraphRangeSlider/Slider.swift | 2 +- Sources/GraphRangeSlider/SliderToggle.swift | 17 +++++------------ 5 files changed, 15 insertions(+), 23 deletions(-) create mode 100644 Sources/GraphRangeSlider/Extensions/Array+.swift diff --git a/Example/Example/ContentView.swift b/Example/Example/ContentView.swift index df8ff7c..3b706fc 100644 --- a/Example/Example/ContentView.swift +++ b/Example/Example/ContentView.swift @@ -7,15 +7,7 @@ struct Element: GraphRangeElement { } struct ContentView: View { - let data: [Element] = [ - .init(x: 10, y: 10), - .init(x: 20, y: 20), - .init(x: 30, y: 30), - .init(x: 40, y: 40), - .init(x: 50, y: 50), - .init(x: 60, y: 60), - .init(x: 70, y: 70), - ] + let data: [Element] = (1...50).map { .init(x: $0 * 10, y: $0 * 10) } @State var selectedData = [Element]() diff --git a/Sources/GraphRangeSlider/Extensions/Array+.swift b/Sources/GraphRangeSlider/Extensions/Array+.swift new file mode 100644 index 0000000..6fb66e2 --- /dev/null +++ b/Sources/GraphRangeSlider/Extensions/Array+.swift @@ -0,0 +1,7 @@ +import Foundation + +extension Array where Element: Comparable { + func argmin() -> Index? { + indices.min(by: { self[$0] < self[$1] }) + } +} diff --git a/Sources/GraphRangeSlider/GraphRangeSlider.swift b/Sources/GraphRangeSlider/GraphRangeSlider.swift index aebe958..3d26e21 100644 --- a/Sources/GraphRangeSlider/GraphRangeSlider.swift +++ b/Sources/GraphRangeSlider/GraphRangeSlider.swift @@ -15,7 +15,7 @@ public struct GraphRangeSlider: View where Data: RandomAccessCollectio @Binding private var selectedData: Data @State private var leftCurrentIndex = 0 @State private var rightCurrentIndex = 0 - @State private var positions = [CGFloat]() + @State private var positions = ContiguousArray() @Environment(\.graphBarWidth) private var graphBarWidth: CGFloat @Environment(\.activeColor) private var activeColor: Color @Environment(\.inactiveColor) private var inactiveColor: Color diff --git a/Sources/GraphRangeSlider/Slider.swift b/Sources/GraphRangeSlider/Slider.swift index f360268..538b3d7 100644 --- a/Sources/GraphRangeSlider/Slider.swift +++ b/Sources/GraphRangeSlider/Slider.swift @@ -1,7 +1,7 @@ import SwiftUI struct Slider: View { - let positions: [CGFloat] + let positions: ContiguousArray @Binding var leftCurrentIndex: Int @Binding var rightCurrentIndex: Int @State private var viewSize = CGSize.zero diff --git a/Sources/GraphRangeSlider/SliderToggle.swift b/Sources/GraphRangeSlider/SliderToggle.swift index 8485fa9..af20431 100644 --- a/Sources/GraphRangeSlider/SliderToggle.swift +++ b/Sources/GraphRangeSlider/SliderToggle.swift @@ -5,7 +5,7 @@ struct SliderToggle: View { case left, right } - let togglePositions: [CGFloat] + let togglePositions: ContiguousArray let limitIndex: Int @Binding var currentIndex: Int @Environment(\.activeColor) private var activeColor: Color @@ -31,23 +31,16 @@ struct SliderToggle: View { .gesture( DragGesture() .onChanged { value in - let nextIndex = min(currentIndex + 1, togglePositions.endIndex - 1) - let previousIndex = max(currentIndex - 1, 0) - switch position { case .left: let locationX = value.location.x - toggleRadius - if togglePositions[nextIndex] < locationX { - currentIndex = min(nextIndex, limitIndex - 1) - } else if locationX < togglePositions[previousIndex] { - currentIndex = previousIndex + if let index = togglePositions.map { abs($0 - locationX) }.argmin() { + currentIndex = min(index, limitIndex - 1) } case .right: let locationX = value.location.x + toggleRadius * 3 - if togglePositions[nextIndex] < locationX { - currentIndex = nextIndex - } else if locationX < togglePositions[previousIndex] { - currentIndex = max(previousIndex, limitIndex + 1) + if let index = togglePositions.map { abs($0 - locationX) }.argmin() { + currentIndex = max(index, limitIndex + 1) } } }