SwiftUI drag from one list to another list

青春壹個敷衍的年華 提交于 2021-01-28 10:14:56

问题


I am trying to drag and drop between to Lists.

What I have tried:

I have found a solution doing it in UIKIt and the using UIViewControllerRepresentable. But that is not what i want.

The other solution was using .onDrag {} on list, but that worked on iPad and didn't work on iPhone.

How to move items between two Lists on iPhone?


回答1:


check this out:

BUT -> as you wrote, it works NOT with list (just on iPad), with VStack you can drag from left to right or right to left.

import SwiftUI


struct BookmarksList2: View {
    @State private var links: [URL] = [
        URL(string: "https://www.apple.com")!
    ]

    var body: some View {
        VStack {
            ForEach(links, id: \.self) { url in
                Text(url.absoluteString)
                    .onDrag {
                        NSItemProvider(object: url as NSURL)
                }
            }
            .onInsert(of: ["public.url"], perform: drop)
            .onDrop(
                of: ["public.url"],
                delegate: BookmarksDropDelegate(bookmarks: $links)
            )
        }
        .navigationBarTitle("Bookmarks")
    }
    private func drop(at index: Int, _ items: [NSItemProvider]) {
           for item in items {
               _ = item.loadObject(ofClass: URL.self) { url, _ in
                   DispatchQueue.main.async {
                       url.map { self.links.insert($0, at: index) }
                   }
               }
           }
       }
}

struct BookmarksList3: View {
    @State private var links: [URL] = [
        URL(string: "https://www.google.com")!
    ]

    var body: some View {
        VStack {
            ForEach(links, id: \.self) { url in
                Text(url.absoluteString)
                    .onDrag {
                        NSItemProvider(object: url as NSURL)
                }
            }
            .onInsert(of: ["public.url"], perform: drop)
            .onDrop(
                of: ["public.url"],
                delegate: BookmarksDropDelegate(bookmarks: $links)
            )
        }
        .navigationBarTitle("Bookmarks")
    }

    private func drop(at index: Int, _ items: [NSItemProvider]) {
        for item in items {
            _ = item.loadObject(ofClass: URL.self) { url, _ in
                DispatchQueue.main.async {
                    url.map { self.links.insert($0, at: index) }
                }
            }
        }
    }
}

struct BookmarksDropDelegate: DropDelegate {
    @Binding var bookmarks: [URL]

    func performDrop(info: DropInfo) -> Bool {
        guard info.hasItemsConforming(to: ["public.url"]) else {
            return false
        }

        let items = info.itemProviders(for: ["public.url"])
        for item in items {
            _ = item.loadObject(ofClass: URL.self) { url, _ in
                if let url = url {
                    DispatchQueue.main.async {
                        self.bookmarks.insert(url, at: 0)
                    }
                }
            }
        }

        return true
    }
}

struct ContentView : View {

    var body: some View {

        HStack {
            BookmarksList2()
            Divider()
            BookmarksList3()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


来源:https://stackoverflow.com/questions/61998954/swiftui-drag-from-one-list-to-another-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!