Drag and drop to open window in SwiftUI app

With UIKit you can open a window via drag and drop by creating a UIDragItem with an NSItemProvider and NSUserActivity object in a collection view.

Is there a similar SwiftUI API to open a window by dragging out a view from a grid? Or can we only manually invoke openWindow from a button?

Post not yet marked as solved Up vote post of Jordan Down vote post of Jordan
478 views
Add a Comment

Replies

It is a little trickier to do in SwiftUI but possible, though I have only tested this on visionOS. You can find the code below. You will also need to update your Info.plist and add NSUserActivityTypes array with your activities you want to open a new window.

import SwiftUI

struct Activity {
    static let openWindow = "com.ericlewis.openWindow"
}

struct ContentView: View {
    
    @State
    private var text = "root"
    
    var body: some View {
        Button(text) {
            // noop, makes it easier to grab and drag.
        }
        .onDrag {
            let payload = "destination payload \(Int.random(in: Int.min...Int.max))"
            
            let userActivity = NSUserActivity(activityType: Activity.openWindow)
            try! userActivity.setTypedPayload(["text": payload])
            let itemProvider = NSItemProvider(object: payload as NSString)
            itemProvider.registerObject(userActivity, visibility: .all)
            return itemProvider
        }
        .onContinueUserActivity(Activity.openWindow) { userActivity in
            if let dict = try? userActivity.typedPayload([String: String].self) {
                self.text = dict["text"]!
            }
        }
    }
}