TechnologiesSwiftUIDrag and Drop

DropInfo struct

iOSmacOStvOSwatchOSvisionOS✓ renders

The current state of a drop.

How it works

DropInfo carries the details of an in-progress or completed drop interaction, giving your drop handler everything it needs to decide how to respond. SwiftUI hands you an instance whenever a drag enters or is released over a view that declares a drop destination, exposing which data types the dragged items conform to, the item providers themselves, and the drop location. Reach for DropInfo inside the closures of the onDrop(of:isTargeted:) family when you need to inspect the payload before accepting it, so you can validate the content type and extract the dragged data rather than blindly accepting any drop.

  1. Receive DropInfo from onDrop(of:isTargeted:)

    A drop destination's perform closure is called with a DropInfo describing the current drop. In the example the closure is typed explicitly as (info: DropInfo) -> Bool, and SwiftUI populates info with the items being released over the view declared by onDrop(of: [.url], isTargeted: nil).

  2. Check the payload with hasItemsConforming(to:)

    Before committing to a drop, ask DropInfo whether its items match the uniform type identifiers you can handle. Here info.hasItemsConforming(to: [.url]) confirms at least one dragged item is a URL; the guard returns false to reject anything else, which tells SwiftUI the drop was not accepted.

  3. Return a Bool to accept or refuse the drop

    The handler's Boolean result is your verdict on the DropInfo: true means you consumed the items, false means you declined. Once the URL check passes, the example sets dropped = true and returns true, signaling success so SwiftUI can finish the interaction.

  4. Drive UI from the drop outcome

    Because the closure runs on a successful drop, it is the right place to mutate view state. Flipping the @State private var dropped flag swaps the Text from "Drag a URL here" to "Item dropped!" and recolors it via foregroundStyle, reflecting what DropInfo reported back to the view.

Try it — Change the type filter in both onDrop(of: [.url], ...) and info.hasItemsConforming(to: [.url]) to [.image] and drag a URL onto the target: the guard now fails, the handler returns false, and the label stays on "Drag a URL here".

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.

DropInfo.swift
struct DropInfoDemo: View {
    @State private var dropped = false

    var body: some View {
        VStack(spacing: 12) {
            Text("Drop Target")
                .font(.headline)
            Text(dropped ? "Item dropped!" : "Drag a URL here")
                .foregroundStyle(dropped ? .green : .secondary)
        }
        .frame(width: 220, height: 120)
        .background(RoundedRectangle(cornerRadius: 12).fill(.gray.opacity(0.15)))
        .onDrop(of: [.url], isTargeted: nil) { (info: DropInfo) -> Bool in
            guard info.hasItemsConforming(to: [.url]) else { return false }
            dropped = true
            return true
        }
        .padding()
    }
}
Live preview
Drop Target Drag a URL here
Drop Target Drag a URL here
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →