首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何为自定义类型- NSPasteboard / Swift设置Pasteboard属性列表

如何为自定义类型- NSPasteboard / Swift设置Pasteboard属性列表
EN

Stack Overflow用户
提问于 2019-08-25 17:14:53
回答 1查看 1.4K关注 0票数 1

我正在开发一个Cocoa应用程序,以便在两个NSTableViews之间拖放文件。我不只是使用URL,我希望使用一个自定义的结构,以便在需要时可以访问更多的数据,而不是不断地调用FileManager。

我相信我需要实现使我的自定义Pasteboard实用程序符合NSPasteboardReading,这样我就可以正确地消化接收表上的数据。

我不确定在处理我在Pasteboard中使用的自定义结构时,需要根据需要设置什么init?(pasteboardPropertyList propertyList: Any, ofType type: NSPasteboard.PasteboardType)函数。

坦率地说,我不知道在这种情况下如何使用属性列表,因为过去我通常只在设置全局应用程序plist时使用它。

可悲的是,这里没有太多的资源。我看到的大多数示例通常都引用了属性列表中的JSON对象。我不确定是否需要将数据从自定义类型中提取到数据或字符串类型的数组中。

这里有任何关于实现的指导,或者更好的关于属性列表可能的指导,我们将不胜感激!

传递给PasteBoard的自定义结构:

代码语言:javascript
复制
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
    }
}

表视图控制器:在这里,我将项目写到黑板上

代码语言:javascript
复制
    func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
        return PasteboardWriter(tidiFile: tableSourceTidiFileArray[row], at: row)
    }

表视图控制器:我想在其中接受删除并移动文件

代码语言:javascript
复制
func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {

            let pasteboard = info.draggingPasteboard
            let pasteboardItems = pasteboard.pasteboardItems


    }

自定义粘贴板实用程序:

代码语言:javascript
复制
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
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-25 17:39:03

首先,为了能够拖放自定义对象,该对象必须是 of NSObject

这是一个快速和脏的非可选类型的实现。使用Codable将数据序列化到属性列表和从属性列表中。综合了协议方法init(from decoderencode(to encoder

init?(pasteboardPropertyList中,您必须解码一个实例并使用标准初始化程序创建一个新实例。

代码语言:javascript
复制
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
    }

}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57648121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档