我正在开发一个Cocoa应用程序,以便在两个NSTableViews之间拖放文件。我不只是使用URL,我希望使用一个自定义的结构,以便在需要时可以访问更多的数据,而不是不断地调用FileManager。
我相信我需要实现使我的自定义Pasteboard实用程序符合NSPasteboardReading,这样我就可以正确地消化接收表上的数据。
我不确定在处理我在Pasteboard中使用的自定义结构时,需要根据需要设置什么init?(pasteboardPropertyList propertyList: Any, ofType type: NSPasteboard.PasteboardType)函数。
坦率地说,我不知道在这种情况下如何使用属性列表,因为过去我通常只在设置全局应用程序plist时使用它。
可悲的是,这里没有太多的资源。我看到的大多数示例通常都引用了属性列表中的JSON对象。我不确定是否需要将数据从自定义类型中提取到数据或字符串类型的数组中。
这里有任何关于实现的指导,或者更好的关于属性列表可能的指导,我们将不胜感激!
传递给PasteBoard的自定义结构:
struct TidiFile {
var url : URL?
var createdDateAttribute : Date?
var modifiedDateAttribute : Date?
var fileSizeAttribute: Int?
//setting for a nil init so this can return nil values in case of failure to set attributes
init( url : URL? = nil,
createdDateAttribute : Date? = nil,
modifiedDateAttribute : Date? = nil,
fileSizeAttribute: Int? = nil) {
self.url = url
self.createdDateAttribute = createdDateAttribute
self.modifiedDateAttribute = modifiedDateAttribute
self.fileSizeAttribute = fileSizeAttribute
}
}表视图控制器:在这里,我将项目写到黑板上
func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
return PasteboardWriter(tidiFile: tableSourceTidiFileArray[row], at: row)
}表视图控制器:我想在其中接受删除并移动文件
func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
let pasteboard = info.draggingPasteboard
let pasteboardItems = pasteboard.pasteboardItems
}自定义粘贴板实用程序:
import Foundation
import Cocoa
class PasteboardWriter: NSObject, NSPasteboardWriting, NSPasteboardReading {
required init?(pasteboardPropertyList propertyList: Any, ofType type: NSPasteboard.PasteboardType) {
// Need to implement
}
var tidiFile : TidiFile
var index: Int
init(tidiFile : TidiFile, at index: Int) {
self.tidiFile = tidiFile
self.index = index
}
func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.tableViewIndex, .tidiFile]
}
func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
switch type {
case .tidiFile:
return tidiFile
case .tableViewIndex:
return index
default:
return nil
}
}
static func readableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.tableViewIndex, .tidiFile]
}
}
extension NSPasteboard.PasteboardType {
static let tableViewIndex = NSPasteboard.PasteboardType("com.bradzellman.tableViewIndex")
static let tidiFile = NSPasteboard.PasteboardType("com.bradzellman.tidiFile")
}
extension NSPasteboardItem {
open func integer(forType type: NSPasteboard.PasteboardType) -> Int? {
guard let data = data(forType: type) else { return nil }
let plist = try? PropertyListSerialization.propertyList(
from: data,
options: .mutableContainers,
format: nil)
return plist as? Int
}
}发布于 2019-08-25 17:39:03
首先,为了能够拖放自定义对象,该对象必须是类 of NSObject。
这是一个快速和脏的非可选类型的实现。使用Codable将数据序列化到属性列表和从属性列表中。综合了协议方法init(from decoder和encode(to encoder。
在init?(pasteboardPropertyList中,您必须解码一个实例并使用标准初始化程序创建一个新实例。
final class TidiFile : NSObject, Codable {
var url : URL
var createdDateAttribute : Date
var modifiedDateAttribute : Date
var fileSizeAttribute: Int
init(url: URL, createdDateAttribute: Date, modifiedDateAttribute: Date, fileSizeAttribute: Int) {
self.url = url
self.createdDateAttribute = createdDateAttribute
self.modifiedDateAttribute = modifiedDateAttribute
self.fileSizeAttribute = fileSizeAttribute
}
convenience init?(pasteboardPropertyList propertyList: Any, ofType type: NSPasteboard.PasteboardType) {
guard let data = propertyList as? Data,
let tidi = try? PropertyListDecoder().decode(TidiFile.self, from: data) else { return nil }
self.init(url: tidi.url, createdDateAttribute: tidi.createdDateAttribute, modifiedDateAttribute: tidi.modifiedDateAttribute, fileSizeAttribute: tidi.fileSizeAttribute)
}
}
extension TidiFile : NSPasteboardWriting, NSPasteboardReading
{
public func writingOptions(forType type: NSPasteboard.PasteboardType, pasteboard: NSPasteboard) -> NSPasteboard.WritingOptions {
return .promised
}
public func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.tidiFile]
}
public func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
if type == .tidiFile {
return try? PropertyListEncoder().encode(self)
}
return nil
}
public static func readableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.tidiFile]
}
public static func readingOptions(forType type: NSPasteboard.PasteboardType, pasteboard: NSPasteboard) -> NSPasteboard.ReadingOptions {
return .asData
}
}https://stackoverflow.com/questions/57648121
复制相似问题