TechnologiesSwiftUIDrag and Drop

DragConfiguration struct

iOSmacOStvOSwatchOSvisionOS✓ renders

The behavior of the drag, proposed by the dragging source.

How it works

DragConfiguration describes the policy of a drag interaction: which operations a source permits as the user moves an item, such as copying, moving, or deleting it. SwiftUI applies a default configuration whenever you make a view draggable, but you supply your own DragConfiguration when the source needs finer control over the allowed operations or the behavior the system offers at the drop location. Reach for it when a plain draggable item isn't expressive enough and the drag's outcome should depend on what the source is willing to allow.

  1. Start from a draggable source

    A DragConfiguration only matters where a drag begins, so you attach it to a view that already participates in a drag. In the example the source is the blue RoundedRectangle, made liftable by .draggable("Photo"), which is the hook a configuration refines.

  2. Declare the allowed operations

    The configuration's core job is to state which drag operations the source supports — for instance allowing a copy while forbidding a move — so the system can present the correct affordance and resolve the drop accordingly. This is what turns the generic lift of .draggable("Photo") into an interaction with defined, source-controlled outcomes.

  3. Provide the transferable payload

    DragConfiguration governs how an item moves, while the item itself is the Transferable value carried by the drag. Here the payload is the "Photo" string passed to .draggable; the configuration shapes the behavior around that value rather than replacing it.

  4. Customize the drag preview

    The preview is the representation the user sees under the pointer during the drag, and it sits alongside the configuration on the same source. The example supplies one through the .draggable trailing closure — a translucent RoundedRectangle filled with .blue.opacity(0.5) — so the configured drag has a clear visual stand-in.

  5. Let the destination respond to the policy

    Because the configuration advertises what operations are permitted, a matching drop destination can accept or reject the item and choose the resulting operation. The VStack and its "Drag the card" Text are only the stage on which this source lives; the configured behavior is what a receiving view ultimately reacts to.

Try it — Wrap the source's payload and preview in an explicit DragConfiguration that allows only a copy operation, then watch the system show a copy affordance instead of a move when you lift the "Photo" card.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

DragConfiguration.swift
struct DragConfigurationDemo: View {
    var body: some View {
        VStack(spacing: 16) {
            Text("Drag the card")
                .font(.headline)
            RoundedRectangle(cornerRadius: 12)
                .fill(.blue.gradient)
                .frame(width: 160, height: 100)
                .overlay(Text("Photo").foregroundStyle(.white))
                .draggable("Photo") {
                    RoundedRectangle(cornerRadius: 12)
                        .fill(.blue.opacity(0.5))
                        .frame(width: 160, height: 100)
                }
        }
        .padding()
    }
}
Live preview
Drag the card Photo
Drag the card Photo
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →