iOS 13.4 beta: onDrop doesn’t work with List or Views inside it

I am trying to use the new onDrop feature of iOS13.4. It works for me on Stacks, Text views, Buttons and such.


However onDrop is not called on a List, or any views (for instance a custom row view, or a button) when they are inside of a list.


This seems like a bug?

Ultimately, what I want to do is drag something from a DetailView, onto a particular row in a List inside a NavigationView, and have it added to the model associated with that row / detail view, but I can't if the List is swallowing the onDrop calls.



in this code you can drag "Test Person" (PersonRow) onto the VStack, registers fine, onto "Another Test Person" (PersonRow) and that registers find, but you cannot drop onto the List itself or the PersonRows inside the List.

//: A UIKit based Playground for presenting user interface
  
import SwiftUI
import PlaygroundSupport

struct Person: Identifiable, Hashable {
    var id = UUID()
    var name: String
}

struct PersonRow: View {
    @State var targeted: Bool = true
    var person: Person
    var body: some View {
        HStack {
            Image(systemName: "person.circle")
            Text(person.name)
            Text(person.id.description)
        }
        .onDrop(of: ["public.utf8-plain-text"], isTargeted: self.$targeted) { item in
            DispatchQueue.main.async {
                print("onDrop PersonRow: \(item.description)")
            }
            return true
        }

        .onDrag {
            let item = NSItemProvider(object: NSString(string: self.person.name))
            item.suggestedName = self.person.name
            print("onDrag: \(item)")
            return item
        }
    }
}

struct MyView : View {
    var people: [Person] = [Person(name: "George"), Person(name: "The Kurruth"), Person(name: "The Other")]
    @State var targeted: Bool = true

    var body: some View {
        VStack {
            Text("Test")
            Text("")
            PersonRow(person: Person(name:"Test Person"))
            Text("---------------------")
            PersonRow(person: Person(name:"Another Test Person"))

            //List() {
                ScrollView() {
                ForEach(people) { person in
                    PersonRow(person: person)
                }
            }
            .onDrop(of: ["public.utf8-plain-text"], isTargeted: self.$targeted) { item in
                DispatchQueue.main.async {
                    print("onDrop ScrollView: \(item.description)")
                }
                return true
            }
        }
    }
}

// Present the view controller in the Live View window
PlaygroundPage.current.setLiveView(MyView())


(edit to tidy code)

Replies

Changing the List to a ScrollView & ForEach does work.

The proposed solution does work but it means loosing other features from List, like an EditMode and the ability to re-arrange and delete items.
I've raised a Feedback issue FB7955283

I encourage others to do so too.