【发布时间】:2017-05-23 06:38:24
【问题描述】:
尽管我有工作代码,但我对我是否对NSPasteboard 采取了正确的方法感到困惑,我正在联系是否有人可以帮助我阐明最佳方法。
自 2012 年以来,Apple 似乎没有任何关于拖放的完整文档,在那个时候,您应该使用的方式(尤其是沙盒应用程序)似乎已经被弃用和改变了实施它。经过一番折腾,我发现当您访问它的路径属性时,拖动的粘贴板提供的文件 URL 显示了它的真实路径(而不是构成 url 的匿名数字字符串),这使得可以使用进行常规复制FileManager。
我的问题是,我在这里遵循正确的程序吗?将从粘贴板获得的NSURL 转换为URL 类型并在copyItem(at:URL, to:URL) 中使用它不起作用(即使将相同的url 复制并粘贴到Safari 中使我能够查看文件)。因此我改用copyItem(atPath:String, toPath:String)。为了进一步研究这一点,URL 类型是否有替代 NSURL(from:NSPasteboard) 的方法?好像应该有。
无论如何,这是我正在工作的代码(请忽略 draggingEntered 中的代码:现在,它只是让测试工作正常,而且我注册NSFilenamesPboardType 但随后忽略它的事实也可以被忽略)。
import Cocoa
class DraggerView: NSView {
let types = [NSURLPboardType, NSFilenamesPboardType]
var directory:URL!
override init(frame: NSRect) {
super.init(frame: frame)
register(forDraggedTypes: types)
if let dir = URL(string:NSTemporaryDirectory())
{
directory = dir
}
}
required init?(coder: NSCoder) {
super.init(coder: coder)
register(forDraggedTypes: types)
if let dir = URL(string:NSTemporaryDirectory())
{
directory = dir
}
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
NSColor.white.set()
NSRectFill(dirtyRect)
}
override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
return NSDragOperation.copy
}
override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
let pboard = sender.draggingPasteboard()
if let types = pboard.types, types.contains(NSURLPboardType) {
// add file name to save to loaction
if let fileURL = NSURL(from:pboard), let filename = fileURL.lastPathComponent {
directory.appendPathComponent(filename)
do {
try FileManager.default.copyItem(atPath:fileURL.path!, toPath:directory.path)
}
catch {
// something went wrong
}
}
return true
}
else { return false }
}
}
最后一点是,在注册拖动类型时,文档一直提到使用 UTI,但我不清楚这延伸到什么程度。我应该用 UTI 替换 NSURLPboardType 和 NSFilenamesPboardType 吗?
【问题讨论】:
-
可能不相关,但文件系统 URL 必须使用
fileURLWithPath方法初始化:URL(fileURLWithPath:NSTemporaryDirectory())。并将directory声明为非可选且为常量 (let)。 -
感谢您的提醒。这是我总是忘记的事情之一。
标签: swift macos nspasteboard nsdragginginfo nsdraggingitem