Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI | onDrag - customize (dragItem) preview image appearance

Tags:

ios

swift

swiftui

I've been wondering if there is any way to customize the preview image of the view that's being dragged when using onDrag?

As you might see, the preview image is by default a slightly bigger opacity image of the view.

From what I have found, a preview image is generated at the very beginning of the dragging process. But I couldn't find a way to change it.

What I mean by customizing is to have some custom image or a preview image of a custom view. (Both without the default opacity)

Does anyone have an idea?

I have tried to use previewImageHandler and in general, read a lot about the NSItemProvider. But for me, it seems like this is something that is not possible for SwiftUI yet?

With UIKit one could have just customized the UIDragItem - something like that using previewProvider: Here

Here is my demo code:

struct ContentView: View {
    
    var body: some View {
        DraggedView()
            .onDrag({ NSItemProvider() })
    }
    
    
    private struct DraggedView: View {
    
        var body: some View {
            RoundedRectangle(cornerRadius: 20)
                .frame(width: 120, height: 160)
                .foregroundColor(.green)
        }
    }
}

I will use this for drag and drop within a LazyVGrid, so custom gestures are unfortunately no option.

One second idea I had would be to have a gesture simultaneously that first changes the item to be dragged to something else and then onDrag starts and returns the NSItemProvider with the preview image which would be then the one I would want. But I couldn't have those two gestures go at the same time, you would have to dismiss one first in order to start the second.

Thank you!

like image 220
Mofawaw Avatar asked Oct 12 '20 10:10

Mofawaw


1 Answers

iOS 15 adds an API to do this - you can specify the View to use for the preview. onDrag(_:preview:)

RoundedRectangle(cornerRadius: 20)
    .frame(width: 120, height: 160)
    .foregroundColor(.green)
    .onDrag {
        NSItemProvider()
    } preview: {
        RoundedRectangle(cornerRadius: 18)
            .frame(width: 100, height: 140)
            .foregroundColor(.green)
    }
like image 158
Jordan H Avatar answered Sep 29 '22 13:09

Jordan H