macOS:nsdraggingItem作为fileurl和数据
我的应用程序显示文件列表(图像、视频、音频、文本),类似于 Finder。
我使用 LazyVGrid,而不是列表或表格视图,因为我想渲染网格,而不仅仅是行。
我想启用将项目从我的应用程序拖动到其他应用程序。其他一些应用程序(例如 Finder)需要放置项目提供程序中的 fileURL,而其他应用程序则需要图像等数据(据我所知,例如 Figma)。
我想让一次拖动多个项目成为可能,据我所知 SwiftUI 的 onDrag 尚不支持(回调必须返回一个 NSItemProvider),除非它是一个列表或表格视图。 所以我使用 NSHostingView
:
class MultiDragNSHostingView<Content>: NSHostingView<Content> where Content: View {
let fileURL: URL
let selectedFileURLs: [URL]
// ...
override func mouseDragged(with event: NSEvent) {
beginDraggingSession(with: [selectedFileURLs.map { url in getDraggingItem(for: url) }], event: event, source: self)
super.mouseDragged(with: event)
}
private func getDraggingItem(for url: URL) -> NSDraggingItem {
// ???
}
}
如果我使用 onDrag { NSItemProvider(contentsOf: fileURL) }
,那么对于 PNG 图像,放置项提供程序将包含这些 registeredTypeIdentifiers
:[“public.png”,“public.file-url”]
。
我的问题是:我应该如何实现上面的 getDraggingItem
,以获得与使用 onDrag
时类似的放置项目提供程序,即同时具有“public.file-url”和“public.png”(或其他图像/视频/音频/文本)注册类型标识符?
我检查了 NSDraggingItem
的初始值设定项,它有一个参数 pasteboardWriter: NSPasteboardWriting
。符合类型例如 NSFilePromiseProvider
和 NSImage
,但我还不知道我需要什么 PasteboardWriter 来回答上面的问题。
My app shows a list of files (images, videos, audios, texts), similar to Finder.
I use LazyVGrid, instead of List or Table views, because I want to render a grid, not just rows.
I want to enable dragging items from my app to other apps. Some other apps (e.g. Finder) require fileURL in the drop item provider, while others require data e.g. image (afaik e.g. Figma).
I want to make it possible to drag multiple items at a time, which afaik SwiftUI's onDrag
doesn't support yet (the callback has to return exactly one NSItemProvider
) unless it's a List or Table view.
So I use an NSHostingView
:
class MultiDragNSHostingView<Content>: NSHostingView<Content> where Content: View {
let fileURL: URL
let selectedFileURLs: [URL]
// ...
override func mouseDragged(with event: NSEvent) {
beginDraggingSession(with: [selectedFileURLs.map { url in getDraggingItem(for: url) }], event: event, source: self)
super.mouseDragged(with: event)
}
private func getDraggingItem(for url: URL) -> NSDraggingItem {
// ???
}
}
If I used onDrag { NSItemProvider(contentsOf: fileURL) }
, then for a PNG image, the drop item provider would contain these registeredTypeIdentifiers
: ["public.png", "public.file-url"]
.
My question is: How should I implement getDraggingItem
above, to get drop item providers similar to when using onDrag
, i.e. having both "public.file-url" and "public.png" (or other image/video/audio/text) registered type identifiers?
I checked the initializer for NSDraggingItem
, it has one param pasteboardWriter: NSPasteboardWriting
. Conforming types are e.g. NSFilePromiseProvider
and NSImage
, but I don't see yet what pasteboardWriter I need to answer my question above.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在您的情况下,您不需要多个项目提供程序,因为 NSItemProvider 可以包含项目的多个表示形式。创建 NSItemProvider 的实例,然后为要注册的每种类型调用 registerDataRepresentation 。
You don't need multiple item providers in your case because NSItemProvider can contain multiple representations of an item. Create an instance of NSItemProvider then call registerDataRepresentation for each type you want to register.