ByteNoteByteNote
放下之前要先接受这次拖动
字

字节笔记本

2026年10月7日 · 约 3 分钟读完

放下之前要先接受这次拖动

API中转
¥120

macOS 上用 AppKit 做拖放。示例是一个视图子类。背景涂成蓝色,注册接受字符串类型。按下鼠标时开始拖,放下时打印剪贴板里的字符串。

拖出去的是一句固定文字

初始化里打开图层,背景用蓝色,并注册拖动类型为字符串。按下时新建剪贴板项,写入 Dragged Item。拖动项的帧用视图边界,内容用一张快照。快照按边界大小建图,锁住焦点,把视图画进去,再解锁。然后用这一项开始拖动会话,事件用当前鼠标事件,源是视图自己。

放下时从拖动信息里取剪贴板第一项,读出字符串。读不到就返回否。读到就打印 Dropped item 和这段文字,并返回是。

使用处把视图放进父视图,帧是横坐标 50、纵坐标 50、宽 100、高 100。父视图要已经在窗口里。只有一块蓝色方块时,它既是拖出的源,也注册了放下。把自己拖到自己身上,才会走进放下方法。对话没有第二块视图。

没有允许操作,放下不会发生

片段没有实现进入拖动时的那个方法,因此没有返回复制或移动之类的操作。系统在进入时得到的是空操作,就不会把这次拖动当成可以放下。后面的放下方法写了也不会被调用。只看到没有打印,先补允许操作,不要先改打印那一句。

源参数传的是视图自己。视图默认不是拖动源。类上也没有写出拖动源协议,没有给出这次允许的操作掩码。要能开始拖,类得满足源的要求。对话的片段没有这段声明。编译若指向源参数,缺的是协议,不是字符串内容。

蓝色方块拖出的是固定句子

注册类型只有字符串。拖进来的若是文件或图片,第一项读不出字符串,放下方法返回否。这和没有进入允许是两种失败。一种是根本不调用放下,一种是调用了但返回否。

快照用的是锁焦点再画。这是片段里的写法。拖动时看到的图来自这一张。图是空的,先看画进去的边界是不是零。帧是 100 乘 100 时,边界不应是零。

两个构造器都调用同一段设置。一个从帧来,一个从编码器来。用界面构建器放上去时走编码器。只改帧那个构造器,从编码器创建的视图不会注册拖动类型。

打印的前缀是 Dropped item。看到这句,说明放下方法已经执行,字符串也读到了。看不到这句,先分清是没进入,还是进入了但类型不对。

进入时不返回操作就不会放下

字符串写死为 Dragged Item。它不是被拖视图的标题,也不是文件名。换成别的句子,打印跟着变。类型仍是字符串。

开始拖动时的帧用的是边界,不是父视图里的那个 50、50。50 和 50 只决定方块放在哪。拖动图像的大小跟方块本身。

对话说这是基本实现,复杂类型、自定义图像、多视图都没有往下写。不要把没出现的文件承诺进这段。当前能核对的就是字符串、蓝色、100 乘 100,以及缺了进入时的允许操作。

父视图的坐标原点在左下还是左上,取决于它是不是翻转坐标系。片段没有翻转。50、50 是未翻转时的位置。方块不在你以为的角上,先看坐标系,不要改拖动字符串。

相关文章

分享: