[英]Drag and drop on a List row in swiftui
I have been trying to implement drag and drop on a List
in SwiftUI.我一直在尝试在 SwiftUI 中的List
上实现拖放。 What I'm trying to do is drag a row on a List
and drop it on a row in the SAME List
, much like the Remainders app on iOS
.我想要做的是在List
上拖动一行并将其放在 SAME List
的一行上,就像iOS
上的 Remainders 应用程序一样。
Note: It's important to note that I'm not trying to rearrange the list but rather make the dropped item a "child" of that row.注意:重要的是要注意,我不是要重新排列列表,而是要使删除的项目成为该行的“子项”。
import SwiftUI
import UniformTypeIdentifiers
struct Item: Identifiable {
let id = UUID()
let title: String
}
struct EditListView: View {
@State private var items: [Item] = [
Item(title: "Apple"),
Item(title: "Banana"),
Item(title: "Papaya"),
Item(title: "Mango")
]
var body: some View {
VStack {
List {
ForEach(items) { item in
Text(item.title)
}
.onDrop(of: [UTType.text], delegate:dropDelegate() )//doesn't work
.onDrag{
NSItemProvider(item: .some(URL(string: "item")! as NSSecureCoding), typeIdentifier: String() )
}
}
Text("Drop Item Here..")
.fontWeight(.heavy)
.onDrop(of: [UTType.text], delegate:dropDelegate() )//works
}
}
}
class dropDelegate: DropDelegate {
func performDrop(info: DropInfo) -> Bool {
print("drop success")
return true
}
}
Dropping on the Text
works.删除Text
有效。
Dropping on the list row fails.删除列表行失败。
Hey unknown i may can help you.嘿未知我可以帮助你。
So it should looks like this..所以它应该看起来像这样..
struct EditListView: View {
@State private var items: [Item] = [
Item(title: "Apple"),
Item(title: "Banana"),
Item(title: "Papaya"),
Item(title: "Mango")
]
@State private var editMode = EditMode.inactive
var body: some View {
NavigationView{
VStack {
List {
ForEach(items) { item in
Text(item.title)
}
}
Text("Drop Item Here..")
.fontWeight(.heavy)
.onDrop(of: [UTType.text], delegate:dropDelegate() )//works
}
}.environment(\.editMode,$editMode)
}
private var addButton : some View {
switch editMode {
case .inactive:
return AnyView(Button(action: onAdd) {Image(systemName: "plus")})
default:
return AnyView(EmptyView())
}
}
}
Now you want to add, delete and move items.现在您要添加、删除和移动项目。 So add the following functions to your struct因此,将以下函数添加到您的结构中
func onAdd(){ items.append(Item(title: "Item \\(Self.count)")) } func onDelete(offsets: IndexSet) { items.remove(atOffsets: offsets) } func onMove(source: IndexSet, destination: Int) { items.move(fromOffsets: source, toOffset: destination) }
This should work :)这应该有效:)
It seems that there is two problems with your code.您的代码似乎有两个问题。
First : many article on the web report that the drop is not working on List component, but you can replace the List by a ScrollView.第一:网络上的很多文章都报告说,该拖放不适用于 List 组件,但您可以将 List 替换为 ScrollView。 Then the drop method will be called.然后将调用 drop 方法。
Second : If you want to apply an action drop by item you have to move you drop method inside the foreach.第二:如果你想逐项应用一个动作,你必须在 foreach 中移动你的 drop 方法。
In the updated code, I just added a sample cell, you can easily reproduce a cell effect by yourself :在更新的代码中,我只是添加了一个示例单元格,您可以轻松地自己重现一个单元格效果:
struct Sample: View {
@State private var items: [Item] = [
Item(title: "Apple"),
Item(title: "Banana"),
Item(title: "Papaya"),
Item(title: "Mango")
]
var body: some View {
VStack {
ScrollView {
ForEach(items) { item in
SampleCell(item: item)
.onDrop(of: [UTType.text], delegate:dropDelegate() )
.onDrag{
NSItemProvider(item: .some(URL(string: "item")! as NSSecureCoding), typeIdentifier: String() )
}
}
}
Text("Drop Item Here..")
.fontWeight(.heavy)
.onDrop(of: [UTType.text], delegate:dropDelegate() )//works
}
}
}
struct SampleCell: View {
var item : Item
var body: some View {
HStack {
Text(item.title).padding()
Spacer()
}.frame(maxWidth:.infinity, minHeight: 60)
.background(Color.gray)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.