iosswiftswiftuidraggable

SwiftUI: How to make .draggable() respond immediately without delay?


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)

Solution

  • 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().