NSView subview blocking drag/drop event
近期在Mac项目中有一个处理鼠标拖拽事件的需求, 大致处理流程是这样的:
- 从 NSView 继承得到一个子类
- 覆盖处理拖拽事件相关方法
- 注册拖拽事件
开始的时候一切都很正常,直到某次发现拖拽到屏幕边缘响应较为灵敏,而拖拽到屏幕中间则不响应事件,APP页面大致是这样的:
问题分析
开始我一直以为是系统事件不太灵光, 后来发现只有在拖动到屏幕中间时候出现这个问题, 这个现象十分奇怪, 后来联想到页面中间有一张图片,猜测是否是因为图片截获了拖拽事件。
那么如何验证呢?其实也很简单,在自定义的NSView 中重载draggingEnded:
方法,同时添加 log,发现鼠标拖拽到页面中间时, 该方法就不再被调用。因此可以得出结论,在自定义的 NSView
中添加的NSImageView
作为 subview 会阻止拖拽事件的传递,原因是 NSImageView
本身可以处理拖拽事件,于是截获了本该自定义NSView
处理的消息。
解决方案
在网上搜索了一下这个问题,发现已经有人给出了解决方案,具体链接:http://stackoverflow.com/questions/5892464/cocoa-nsview-subview-blocking-drag-drop
提供的解决方案有以下几种:
- 不使用
NSImageView
,而是采用自定义NSView
的方式,然后重写drawRect:
方法进行图片渲染。这个办法十分笨拙,并且不太方便。 - 调用
unregisterDraggedTypes
方法,这样NSImageView
就不会监听拖拽事件了,完美解决。