gpt4 book ai didi

swift - 如何为自定义类型设置粘贴板属性列表 - NSPasteboard/Swift

转载 作者:行者123 更新时间:2023-11-28 13:29:28 26 4
gpt4 key购买 nike

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

我认为我需要使我的自定义粘贴板实用程序符合 NSPasteboardReading,这样我才能正确消化接收表上的数据。

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

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

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

非常感谢此处关于实现的任何指导,或者关于属性列表的可能性的更好指导!

传递给粘贴板的自定义结构:

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
}
}

TableView Controller :我将项目写入粘贴板的位置

    func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
return PasteboardWriter(tidiFile: tableSourceTidiFileArray[row], at: row)
}

TableView Controller :我想接受放下并移动文件的地方

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
}
}

最佳答案

首先,要能够拖放自定义对象,该对象必须是 NSObject 的子

这是非可选类型的快速实现。使用 Codable 将数据序列化到 Property List 或从 Property List 序列化。合成协议(protocol)方法init(from decoderencode(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
}

}

关于swift - 如何为自定义类型设置粘贴板属性列表 - NSPasteboard/Swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57648121/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com