Swift4に移行した後、次のコードでコンパイルエラーが発生します。
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)
}
}
Swift4のNSFilenamesPboardType
の代替品は何ですか? file name
のドラッグタイプ(私の場合はmp3、wav、aiff、...ファイル)をSwift4に登録する方法は?
ありがとう!
この拡張機能との下位互換性を解決しました:
extension NSPasteboard.PasteboardType {
static let backwardsCompatibleFileURL: NSPasteboard.PasteboardType = {
if #available(OSX 10.13, *) {
return NSPasteboard.PasteboardType.fileURL
} else {
return NSPasteboard.PasteboardType(kUTTypeFileURL as String)
}
} ()
}
つまり、NSPasteboard.PasteboardType.backwardsCompatibleFileURL
を使用できます
非推奨の変数NSFilenamesPboardType
に対してここに示されている創造的な回避策が好きです。この質問を調べた後、非推奨ではない同等のアプローチで前進する方法は、readObjects(forClasses:options:)
を使用することです。これは、将来のmacOSで実行できるWRTの安全性も高くなります。次の例のように実装され、ストーリーボードにNSView
が登録されていることに基づいて、Swift 4.1でテストされます。
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) }
}
}
readObjects
のクラス配列パラメーターはタイプ[AnyClass]
であるため、NSURL
の代わりにURL
を使用する理由です。
私も同じ問題に直面しており、私の解決策はkUTTypeURL
でカスタム_NSPasteboard.PasteboardType
_を作成することです。これが最も適切な方法であるかどうかはわかりませんが(おそらくそうではないと思います)、少なくとも一時的な回避策としては機能します。
_ let draggedType = NSPasteboard.PasteboardType(kUTTypeURL as String)
self.tableView?.registerForDraggedTypes([draggedType])
_
さらに、新しい_NSPasteboard.PasteboardType
_には.fileNameType(forPathExtension: "foo")
メソッドがあります。試してみてください。しかし、どういうわけか、私の場合は機能しません。
マークブリッジスの答え と slboatの答え の組み合わせを使用して、これは私が思いついた解決策です:
extension NSPasteboard.PasteboardType {
/// The name of a file or directory
static let fileName: NSPasteboard.PasteboardType = {
return NSPasteboard.PasteboardType("NSFilenamesPboardType")
}()
}
これは私のテストでは期待どおりに機能します。
Swift4、Swift5:
一時的な回避策の一部ですが、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") }
次に、
var acceptableTypes: Set<NSPasteboard.PasteboardType> { return [.URL, .fileURL, .pdf, .png, .rtf, .rtfd, .tiff, finderNode, webarchive] }
次に、ビューで使用したロードメソッド:
// Intercept drags
registerForDraggedTypes(Array(acceptableTypes))
Swift 5
//MARK:- Managing a Dragging Session After an Image Is Released
override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
let fetched = sender.draggingPasteboard.readObjects(forClasses: [NSURL.self], options: nil)?
.map({ (argv) -> String? in
guard let url = argv as? URL else{
return nil
}
return url.path
}).compactMap({$0})
guard let result = fetched else{
return false
}
// handle the result
print(result)
return true
}