【问题标题】:How to implement drag and drop to 3rd party apps in SwiftUI on macOS如何在 macOS 上的 SwiftUI 中实现拖放到 3rd 方应用程序
【发布时间】:2021-10-20 10:11:44
【问题描述】:

我已尝试向 Google 寻求答案,但我发现的只是如何接受来自其他应用程序的拖放并在单个应用程序中拖放,而且主要关注 iOS,而与 macOS 相关的资源并不多。

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

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

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

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

同样的东西拖到桌面(从技术上讲是一个全屏 Finder 窗口):

实施中缺少什么?

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

【问题讨论】:

  • @Asperi 这不是真的。我使用的应用程序可以通过将其视图上的图像拖动到 finder 以将图像保存到文件中来放置在 finder 上。虽然我很确定这些应用程序不是使用 SwiftUI 构建的。参见 Apple 的示例:developer.apple.com/documentation/appkit/…

标签: macos swiftui drag-and-drop


【解决方案1】:

你需要导出文件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

【讨论】:

  • 这正是我所缺少的,它就像一个魅力!谢谢菲利普。
猜你喜欢
  • 2021-02-13
  • 2021-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-11
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多