TechnologiesSwiftUIDrag and Drop

DropConfiguration struct

iOSmacOStvOSwatchOSvisionOS✓ renders

Describes the behavior of the drop.

How it works

DropConfiguration describes how a view should respond while a drag is hovering over it and when its contents are released onto it. It carries the rules of a drop interaction — which payloads are accepted and how the destination reacts — so that a view can act as a well-behaved drop target without you wiring up the underlying platform drag-and-drop machinery yourself. Reach for it when you want a region of your interface to receive items dragged from elsewhere in your app or from another app, and you need fine-grained control over that acceptance behavior beyond the defaults.

  1. Declare a drop target with dropDestination(for:action:isTargeted:)

    A DropConfiguration only matters in the context of a view that has been marked as able to receive a drop. You establish that target with the dropDestination(for:) modifier, naming the payload type the destination understands — here String.self — so SwiftUI knows which dragged items are eligible to land on this view.

  2. Handle the released payload in the action closure

    The drop's behavior is realized in the action closure, which fires when the user releases items over the target. It receives the decoded items and the drop location, and returns a Bool indicating whether the drop was accepted. In the example the closure does dropped.append(contentsOf: items) and returns true, committing the dragged strings to state.

  3. Track hover state through the isTargeted callback

    Part of configuring a drop is reacting to a drag merely moving over the target, before anything is released. The isTargeted callback delivers a Bool each time the pointer enters or leaves the region; binding it with isTargeted: { isTargeted = $0 } lets the view reflect that the drop is live and ready to receive.

  4. Give the target visible feedback while it accepts

    Because the hover state is captured in @State private var isTargeted, you can drive the target's appearance from it. The example swaps its .background to Color.accentColor.opacity(0.2) while a drag is over it, turning the configuration's targeting signal into the affordance the user sees.

Try it — Change the action closure to return false instead of return true so the drop is rejected, and watch that dropped stays empty even though the target still highlights on hover.

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.

DropConfiguration.swift
struct DropConfigurationDemo: View {
    @State private var dropped: [String] = []
    @State private var isTargeted = false

    var body: some View {
        VStack(spacing: 12) {
            Text("Drop text here")
                .frame(maxWidth: .infinity)
                .frame(height: 100)
                .background(isTargeted ? Color.accentColor.opacity(0.2) : Color(.secondarySystemBackground))
                .clipShape(RoundedRectangle(cornerRadius: 12))
                .dropDestination(for: String.self) { items, location in
                    dropped.append(contentsOf: items)
                    return true
                } isTargeted: { isTargeted = $0 }

            if !dropped.isEmpty {
                Text("Dropped: \(dropped.joined(separator: ", "))")
                    .font(.footnote)
            }
        }
        .padding()
    }
}
Live preview
Drop text here Dropped: {dropped.joined(separator: ", ")}
Drop text here Dropped: {dropped.joined(separator: ", ")}
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →