In my SwiftUI application, the drag and drop feature is a core functionality, especially on one specific screen where it's used frequently.
By default, there's a small delay before the drag starts (a long press), but I would like the user to be able to grab and move an item immediately without waiting. Is there a simple way to make .draggable() respond instantly, without requiring a long press?
Any guidance would be greatly appreciated! I’d prefer to avoid re-implementing the whole feature with DragGesture, as my app is already set up with .draggable().
Here’s what I’ve tried so far:
Setting allowHitTesting to false — Drag and drop doesn't work at all. Tried running in both normal and debug modes — Same behavior persists. Enabled EditMode — Same behavior persists.
Text(s)
.padding()
.background(.red)
.draggable(s)
The default behavior of .draggable()
sometimes involves a delay, especially on mobile devices where it expects a long-press gesture before starting. To make it respond instantly, you can use a simultaneous gesture that triggers a drag right away.
you can use the DragGesture
and combine it with .gesture()
for instant drag responses.
struct InstantDraggableView: View {
@State private var offset: CGSize = .zero // To track the position
var body: some View {
Text("Drag Me")
.padding()
.background(Color.blue)
.cornerRadius(10)
.foregroundColor(.white)
.offset(offset) // Update position based on drag
.gesture(
DragGesture()
.onChanged { gesture in
offset = gesture.translation // Update offset as user drags
}
.onEnded { _ in
// Optional: Add logic if you want to reset or constrain the drag
}
)
}
}
struct InstantDraggableView_Previews: PreviewProvider {
static var previews: some View {
InstantDraggableView()
}
}
Instead of relying on .draggable()
(which has built-in delays), using DragGesture()
gives you full control over the dragging behavior.
If you need to combine this with other gestures (like tap or long-press), you can use .simultaneousGesture()
.