17

我很难让 NSPasteboard 工作,所以请原谅我缺乏理解。

我想要的只是一种简单的方法来从粘贴板中写入和检索仅适用于我的应用程序的 NSUInteger 值。我所做的就是在我的应用程序中拖放一个项目,所以我在粘贴板中需要的只是项目的 ID。

我曾尝试研究 NSPasteboardItemDataProvider 和 NSPasteboardItem 以及 NSData,但他们都有复杂的方式来做如此简单的事情。事实上,我不知道做如此简单的事情的正确方法是什么——周围的每个样本似乎都在处理字符串类型,或者更复杂的事情。[NSMutable SetData] 选择器似乎也不存在,即使代码中没有警告。

如果有人能指出我正确的方向,我将不胜感激。:)

编辑:我正在使用 [dragImage ...] 来帮助我进行拖动操作。

4

2 回答 2

48

NSPasteboard 有两种使用方法。

较旧的方法:自己将数据固定到板上

首先,您必须声明将放在粘贴板上的类型。您还指定了一个“拥有”粘贴板的对象,这意味着这是将内容放在粘贴板上的对象。

下一步是将数据放在粘贴板上。此步骤是可选的。

“可选的?!”,你问。是的:如果您没有将您声明的任何类型的数据放在粘贴板上,并且粘贴板随后需要该数据(粘贴/删除),那么粘贴板会向您(所有者)询问它。这被称为有希望的数据,当数据的复制(大)或生成成本很高时,这很好。

有五种方法可以将东西放在粘贴板上(除了被要求提供):

较新的方法:将对象固定到板上并让它们将自己变成数据

Snow Leopard 中引入的新热点是让您的对象本身能够将自己写入粘贴板。这确实要求他们了解您在粘贴板上想要的所有关于他们自己的信息,包括标识符。

您需要使您的对象同时符合NSPasteboardWritingNSPasteboardReading

既然您知道了旧的方式,那么编写协议看起来会非常熟悉。粘贴板询问您的对象它将自己表示为什么类型,然后向它询问每种类型的属性列表对象。(该协议还提供了一种承诺类型的方法,而不是立即请求它们的数据。)

要将符合 NSPasteboardWriting 的对象复制到粘贴板,请向粘贴板发送一条clearContents消息(在新方式中是必需的,在旧方式中是可选的),然后writeObjects:传递要复制的对象数组。

如您所料,阅读协议是相反的。要粘贴,请向粘贴板发送一条readObjectsForClasses:options:消息。粘贴板询问这些类中的每一个它会识别什么类型,然后(可选地)尝试从粘贴板上的内容实例化它们中的一个或多个

这样做的缺点是,特别是在涉及重用标识符的情况下,它最终可能会破坏模型层与控制器层的分离。如果您希望它返回具有该标识符的现有对象,您的读取初始化程序将需要知道如何处理该标识符。这意味着它需要与控制器对话(不好)或复制控制器的查找代码(更糟)。

我不知道使用新协议实现移动拖放(包括但不限于重新排序)而不遇到此问题的好方法。对于复制拖放(包括但不限于跨进程),这很好,因为您不需要标识符 - 只需在一端生成数据并在另一端创建新副本.

新方法的好处是处理多个项目更加理智。在旧的方式中,只有一个“项目”——实际上,根本没有任何项目的概念——有多种类型。如果您想复制或拖动多个事物,您可以创建一个数组并将其复制为某种类型的单个属性列表,然后在另一端从该单个属性列表中重新创建/检索多个事物。较新的方式明确支持一个或多个项目;复制多个东西时,您只需将它们全部传递给writeObjects:.

您的案例:单个 NSUInteger 标识符

将它装在一个 NSNumber (这是一个属性列表)中,并以旧的方式使用它。

于 2011-08-30T18:13:52.700 回答
0

要跟进Peter Hosey的回答,请查看我的 GitHub Helium端口的PlaylistViewController.swift 。该模块处理自定义对象的拖放以及与 WKWebView 的交互。

这是一项正在进行的工作,采用新的闪亮粘贴板。

于 2019-10-28T13:09:29.430 回答