如何在 macOS 上的 SwiftUI 中实现拖放至第 3 方应用程序

Wey*_* Ng 8 macos drag-and-drop swiftui

我试图通过 Google 寻找答案,但我发现的只是如何接受其他应用程序的拖放并在单个应用程序中拖放,而且主要集中在 iOS 上,而没有很多 macOS 相关资源。

我编写了一个 macOS 工具栏应用程序,试图对该应用程序以编程方式创建的图像实现拖放,并且仅在内存中作为 NSImage 进行拖放。为了允许图像可拖动,我实现了一个 DraggableImage 结构来代替ImageSwiftUI 视图中的视图:

struct DraggableImage: View {
    let image: NSImage

    var body: some View {
        Image(nsImage: image)
            .resizable()
            .scaledToFit()
            .padding()
            .onDrag {
                guard let tiffRepresentation = image.tiffRepresentation,
                      let bitmapImage = NSBitmapImageRep(data: tiffRepresentation),
                      let bitmapRepresentation = bitmapImage.representation(using: .png, properties: [:]) else {

                    return NSItemProvider(item: image.tiffRepresentation as NSSecureCoding?, typeIdentifier: kUTTypeTIFF as String)
                }

                let provider = NSItemProvider(item: bitmapRepresentation as NSSecureCoding?,
                                              typeIdentifier: kUTTypePNG as String)

                provider.previewImageHandler = { (handler, _, _) -> Void in
                    handler?(bitmapRepresentation as NSSecureCoding?, nil)
                }

                return provider
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我将图像拖动到 TextEdit 或电子邮件应用程序等应用程序上,DraggableImage 结构将按预期工作。见下文:

将 DraggableImage 拖放到 TextEdit 文档中

但是,我无法将图片拖动到任何基于文件的应用程序(例如 Finder 窗口)上。见下文:

将 DraggableImage 拖放到 Finder 窗口

同样的事情也可以拖到桌面(从技术上讲,这是一个全屏 Finder 窗口):

将 DraggableImage 拖放到桌面

实施过程中还缺少什么?

PS:完整的演示项目托管在GitHub上,供对实施感兴趣的人使用。

Phi*_*hov 9

您需要导出文件URL而不是Data,以便 MacOS 可以复制该文件。

基本示例:

let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("dragExport.png")
try! bitmapRepresentation.write(to: url)

let provider = NSItemProvider(item: url as NSSecureCoding?, typeIdentifier: kUTTypeFileURL as String)
provider.suggestedName = url.lastPathComponent
Run Code Online (Sandbox Code Playgroud)