How does the drag & drop work in swiftui on iOS 14?

Viewed 1006

I am experimenting with drag & drop to later include it into my app.

I come up with a working solution which allows to drag an item from a VStack and it works just fine on iOS 13.5.

Unfortunately, the same code doesn't work on iOS 14.0 simulator (Xcode 12 beta 3).

iOS 13.5: On Item drop, first loadData is called and then object is called and providers in onDrop contains an item

iOS 14.0: On Item drop no functions are called and providers in onDrop is empty

I am not able to figure out if iOS 14.0 requires additional code or this is an issue of iOS 14.

Any idea?


struct ContentView: View {
    @ObservedObject var model = Model()
    var body: some View {
        HStack {
            Spacer()
            VStack {
                ForEach(model.items, id: \.name) { item in
                    ItemView(item: item)
                }
            }
            Spacer()
            DropView().environmentObject(model)
        }
    }
}
struct ItemView: View {
    var item: Item
    var body: some View {
        Text(item.name)
            .onDrag({
                    NSItemProvider(object: self.item)
                })
    }
}
struct DropView: View {
    @EnvironmentObject var model: Model
    var body: some View {
        Text("Drop Here")
            .onDrop(of: [Item.typeIdentifier], isTargeted: nil) { providers, position in
                print("providers \(providers) position \(position)")
                guard let provider = providers.first(where: { provider in provider.hasItemConformingToTypeIdentifier(Item.typeIdentifier) })
                else {
                    return false
                }
                provider.loadObject(ofClass: Item.self) { reading, _ in
                    guard let item = reading as? Item else {
                        return
                    }
                    DispatchQueue.main.async {
                        self.model.items.removeAll(where: { a in a.name == item.name })
                    }
                }
                return true
            }
    }
}
class Model: ObservableObject {
    @Published var items = [
        Item(name: "Item 1"),
        Item(name: "Item 2"),
        Item(name: "Item 3"),
        Item(name: "Item 4"),
    ]
}
class Item: NSObject {
    public static let typeIdentifier = "dnd.item"
    var name: String
    init(name: String) {
        self.name = name
        super.init()
    }
}

0 Answers
Related