Skip to content

Commit 34eb6dd

Browse files
committed
feat(ios): change pos on click
1 parent 6df3341 commit 34eb6dd

1 file changed

Lines changed: 39 additions & 7 deletions

File tree

ios/SeekBar/SeekBar/SeekBar.swift

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import SwiftUI
3535
/// ```
3636
///
3737
/// Additionally, the `onEditingChanged` closure allows you to perform various animations or change the state.
38-
///
38+
///
3939
/// ```swift
4040
/// @State private var progress = 0.5
4141
/// @State private var isEditing = false
@@ -68,6 +68,8 @@ public struct SeekBar: View {
6868
private let onEditingChanged: (Bool) -> Void
6969

7070
@State private var dragStartOffset: CGFloat = 0
71+
// Threshold to distinguish between taps and drags
72+
private let tapThreshold: CGFloat = 3
7173

7274
public var body: some View {
7375
GeometryReader { proxy in
@@ -78,23 +80,53 @@ public struct SeekBar: View {
7880
Track(value: value, bufferedValue: bufferedValue, bounds: bounds)
7981
.frame(height: trackDimensions.trackHeight)
8082
.allowsHitTesting(allowsTrackHitTesting)
81-
.gesture(dragGesture(availableWidth: availableWidth))
83+
.gesture(trackGesture(availableWidth: availableWidth))
8284

8385
Handle()
8486
.frame(width: handleSize, height: handleSize)
8587
.opacity(isDisplayOnlyTrack ? 0 : 1)
8688
.offset(x: calculatePosition(for: value, within: bounds, with: availableWidth))
8789
.allowsHitTesting(allowsHandleHitTesting)
88-
.gesture(dragGesture(availableWidth: availableWidth))
90+
.gesture(handleGesture(availableWidth: availableWidth))
8991
}
9092
}
9193
.frame(height: seekBarMaxHeight)
9294
}
9395

94-
/// Creates a `DragGesture` to handle dragging interactions.
95-
///
96-
/// - Parameter availableWidth: The available width for calculating drag positions.
97-
private func dragGesture(availableWidth: CGFloat) -> some Gesture {
96+
/// Creates a gesture for the track that handles both taps and drags
97+
private func trackGesture(availableWidth: CGFloat) -> some Gesture {
98+
// Use a simultaneous gesture to handle both taps and drags
99+
SimultaneousGesture(
100+
TapGesture()
101+
.onEnded { _ in
102+
// Tap handling not needed here as we'll handle it in the drag gesture
103+
},
104+
DragGesture(minimumDistance: 0)
105+
.onChanged { dragValue in
106+
let distance = abs(dragValue.startLocation.x - dragValue.location.x)
107+
108+
if distance <= tapThreshold {
109+
// Treat as tap - immediate seek
110+
onEditingChanged(true)
111+
value = normalizedValue(for: dragValue.location.x, within: bounds, with: availableWidth, step: step)
112+
} else {
113+
// Treat as drag
114+
onEditingChanged(true)
115+
if isActionMoveWithValue {
116+
value = normalizedValue(for: dragValue.location.x, within: bounds, with: availableWidth, step: step)
117+
}
118+
updateValueWithDrag(dragValue: dragValue, availableWidth: availableWidth)
119+
}
120+
}
121+
.onEnded { _ in
122+
dragStartOffset = 0
123+
onEditingChanged(false)
124+
}
125+
)
126+
}
127+
128+
/// Creates a gesture specifically for the handle (drag only)
129+
private func handleGesture(availableWidth: CGFloat) -> some Gesture {
98130
DragGesture(minimumDistance: 0)
99131
.onChanged { dragValue in
100132
onEditingChanged(true)

0 commit comments

Comments
 (0)