【问题标题】:Drag and drop on a List row in swiftui在swiftui中拖放列表行
【发布时间】:2021-12-24 03:31:20
【问题描述】:

我一直在尝试在 SwiftUI 中实现对 List 的拖放。我要做的是在List 上拖动一行并将其放在同一List 中的一行上,就像iOS 上的Remainders 应用程序一样。

注意:重要的是要注意,我不是要重新排列列表,而是要使删除的项目成为该行的“子项”。

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
    }
}

放弃Text 作品。

删除列表行失败。

【问题讨论】:

  • 在您的最终解决方案中是否需要重新排列并放入子列表?还是只需要删除到子列表?
  • 我想同时移动到子列表并重新排列。
  • 我不认为这是一个答案,但在昨晚玩这个的过程中,我确实发现你可以以你想要的方式在两个相邻的列表之间拖放,而无需任何特殊工作。所以我搞砸了两种可能的解决方案,它们基本上将两个列表分层并在它们之间分配拖放。一种解决方案与默认拖动交互不匹配,因为它没有在长按拖动时提升项目(您必须先移动拖动),另一种解决方案没有在悬停时以默认方式突出显示单元格降低。不确定是否对其中任何一个感兴趣?
  • 两个分层列表的想法听起来很有趣。无论如何,即使它不是一个完整的答案,我也可以看看代码?

标签: swift swiftui drag-and-drop swiftui-list


【解决方案1】:

您的代码似乎有两个问题。

第一 : 网上很多文章都报告说 drop 不适用于 List 组件,但是您可以将 List 替换为 ScrollView。然后会调用 drop 方法。

第二:如果你想逐项应用一个动作,你必须在 foreach 中移动你的 drop 方法。

在更新的代码中,我只是添加了一个示例单元格,您可以轻松地自己重现一个单元格效果:

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)
    }
}

【讨论】:

  • 此实现可以在一行上进行拖放,但它删除了重新排列功能。
  • 好的,所以我认为您实际上(2021 年 11 月)无法意识到您想要什么,因为 onMove 和 OnInsert 仅在 List 而不是 ScrollView 中可用。
  • 你可能是对的。关于同一问题,我已经看到了几个未回答的问题。根据我今天采访的一位 Apple 开发者技术支持工程师的说法,重新排列和拖放都可以使用 LazyVStack(不可能使用列表)来实现。然而,据 DTS 称,目前还没有关于如何实现这一目标的文档。
猜你喜欢
  • 1970-01-01
  • 2019-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-13
  • 2020-08-30
  • 1970-01-01
相关资源
最近更新 更多