如何在 SwiftUI 中对表行使用 Transferable

Yak*_*hzi 6 macos ios swift swiftui

在 WWDC 2022 上,Apple 推出了Transferable协议,以简单的方式支持拖放操作。如何对 SwiftUI表(而非列表)使用这项新技术(与新的draggabledropDestination修饰符结合使用) ?

TableRowContent不支持draggable修饰符dropDestination。此外,当将修改器直接应用于 s 中的视图时TableColumn,拖放操作将仅适用于该特定单元格,而不适用于整行。将修改器添加到所有单元格时,在例如行内的空白区域中拖动时,它仍然不起作用。

struct Item: Identifiable, Codable, Transferable {
    let id = UUID()
    let text: String

    static var transferRepresentation: some TransferRepresentation {
        CodableRepresentation(contentType: .text)
    }
}

struct Test: View {
    var body: some View {
        Table {
            TableColumn("Column 1") { item in
                Text(item.text)
                    .draggable(item) // This does only work when dragging not in the space between two columns
            }
            TableColumn("Column 2") { item in
                Text(item.text)
                    .draggable(item) // This does only work when dragging not in the space between two columns
            }
        } rows: {
            ForEach([Item(text: "Hello"), Item(text: "World")]) { item in
                TableRow(item)
                    .draggable(item) // This causes a compile-time error
                    .itemProvider { ... } // This does not work with Transferable and thus support my use case
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想要与itemProvider修饰符和最近添加的contextMenu修饰符类似的行为TableRowContent ,它允许对整个表行进行相应的操作。我无法使用itemProvider,因为它需要返回 NSItemProvider 这不支持我将文件从网络驱动器拖动到 Mac 硬盘驱动器的用例。

Yak*_*hzi 3

我发现你可以Transferable在以下位置注册一个对象NSItemProvider

TableRow(item)
    .itemProvider {
        let provider = NSItemProvider()
        provider.register(item)
        return provider
    }
Run Code Online (Sandbox Code Playgroud)

不幸的是,itemProvider当拖动会话开始时而不是执行放置时,已经调用了闭包。但我想这个问题是另一个需要回答的问题。