可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
After migrating to Swift4 the following code raise compile error:
public final class MediaItemView: NSView {
public override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
// error: 'NSFilenamesPboardType' is unavailable in Swift:
// use 'NSPasteboard.writeObjects(_:)' with file URLs
let draggedTypes: [NSPasteboard.PasteboardType] = [NSFilenamesPboardType]
registerForDraggedTypes(draggedTypes)
}
}
What is a replacement for NSFilenamesPboardType
in Swift4? How to register drag type of file name
(in my case mp3, wav, aiff, ... files) in Swift4?
Thanks!
回答1:
I've solved backwards compatibility with this extension:
extension NSPasteboard.PasteboardType {
static let backwardsCompatibleFileURL: NSPasteboard.PasteboardType = {
if #available(OSX 10.13, *) {
return NSPasteboard.PasteboardType.fileURL
} else {
return NSPasteboard.PasteboardType(kUTTypeFileURL as String)
}
} ()
}
Which means you can use NSPasteboard.PasteboardType.backwardsCompatibleFileURL
回答2:
i use this as the solution
//Temp solution for this
let NSFilenamesPboardTypeTemp = NSPasteboard.PasteboardType("NSFilenamesPboardType")
self.zipView.registerForDraggedTypes([NSFilenamesPboardTypeTemp])
it's seem a bug from apple,them marked the api as work in 10.13 only.
回答3:
I like the creative workarounds presented here for the deprecated variable NSFilenamesPboardType
. After looking into this question, a way to move forward with an equivalent non-deprecated approach is to use readObjects(forClasses:options:)
. This would also be safer WRT being able to run on future macOSes. It would be implemented like the following example, tested with Swift 4.1, based on having an NSView
registered in a storyboard.
override func awakeFromNib()
{
registerForDraggedTypes([.fileURL])
}
override func draggingEnded(_ sender: NSDraggingInfo)
{
sender
.draggingPasteboard()
.readObjects(forClasses: [NSURL.self],
options: nil)?
.forEach
{
// Do something with the file paths.
if let url = $0 as? URL { print(url.path) }
}
}
Since the class array parameter for readObjects
is of type [AnyClass]
that is the reason for the use of NSURL
instead of URL
.
回答4:
I'm also running into the same issue and my solution is creating a custom NSPasteboard.PasteboardType
with kUTTypeURL
. I'm not sure if this is the most proper way (and I suppose not), but it works at least for temporal workaround.
let draggedType = NSPasteboard.PasteboardType(kUTTypeURL as String)
self.tableView?.registerForDraggedTypes([draggedType])
Furthermore, the new NSPasteboard.PasteboardType
has .fileNameType(forPathExtension: "foo")
method. You should give a try. However somehow, it doesn't work in my case.
回答5:
Using a combination of Mark Bridges' answer and slboat's answer, this is the solution I've come up with:
extension NSPasteboard.PasteboardType {
/// The name of a file or directory
static let fileName: NSPasteboard.PasteboardType = {
return NSPasteboard.PasteboardType("NSFilenamesPboardType")
}()
}
This works as expected in my testing.
回答6:
Swift4, Swift5:
Well part temporary workaround but working for Swift4/5:
var chromeType: NSPasteboard.PasteboardType { return NSPasteboard.PasteboardType.init(rawValue: "org.chromium.drag-dummy-type") }
var finderNode: NSPasteboard.PasteboardType { return NSPasteboard.PasteboardType.init(rawValue: "com.apple.finder.node") }
var fileURLs: NSPasteboard.PasteboardType { return NSPasteboard.PasteboardType.init(rawValue: "NSFilenamesPboardType") }
var webarchive: NSPasteboard.PasteboardType { return NSPasteboard.PasteboardType.init(rawValue: "com.apple.webarchive") }
then aggregate as
var acceptableTypes: Set<NSPasteboard.PasteboardType> { return [.URL, .fileURL, .pdf, .png, .rtf, .rtfd, .tiff, finderNode, webarchive] }
then use in view did load method:
// Intercept drags
registerForDraggedTypes(Array(acceptableTypes))