通过我的窗口控制器的keyDown:方法,我成功地能够对键盘事件作出反应
执行鼠标拖动时出现问题:
键盘事件似乎被延迟,只会在鼠标上启动。
要明确,我的意思是:
•在窗口控制器的keyDown中放置一个日志语句:方法
•启动您的应用程序,执行一些拖动操作(例如,在NSSlider上)
•在保持阻力的同时,按任意键:没有任何记录到控制台
•释放拖动:日志出现,是的...
我正在拖动的控件是一个自定义的NSSlider 我已经使用“鼠标跟踪循环”方法实现了拖动机制。 据我所知,在拖动时,NSApplication的主要运行循环模式正在切换到NSEventTrackingRunLoopMode,从而限制了传入事件。
所以,我只是添加了NSKeyDownMask& NSKeyUpMask在我的跟踪循环中并且在受到欢迎时,相应地称为self.nextResponder keyDown / up:方法。 我的问题已经解决了这个特定的自定义子类。
但是可可的原生控制怎么样?我无法编写该异常代码......
我曾希望NSEvent的“addLocalMonitorForEventsMatchingMask:”方法 但唉,doc说:“不会被嵌套事件跟踪循环所消耗的事件调用,例如控制跟踪,菜单跟踪或窗口拖动”。
那么,无论应用程序的runloop模式如何,是否有接收键盘事件的直接解决方案?
答案 0 :(得分:2)
正如您在NSEvent
班级'的文档中找到的那样addGlobalMonitorForEventsMatchingMask:handler:
,此限制是设计使然。
但是,您可以通过使用IOKit框架(特别是IOHID部分)来接收它,以接收低级别设备事件/中断。我最近不得不这样做,以便在鼠标拖动过程中跟踪一些特定的按键。
基本要点是使用IOHIDManagerCreate()
创建一个IOHID管理器,然后将管理员的类型添加到管理器中,它应该"监控"使用IOHIDManagerSetDeviceMatchingMultiple()
,通过IOHIDManagerRegisterInputValueCallback()
向管理员注册回调,为IOHIDManagerScheduleWithRunLoop()
的经理安排正确的运行循环,最后使用IOHIDManagerOpen()
打开经理。
要在鼠标拖动期间获取这些低级别事件,请在单独的线程中执行此设置。在为管理器安排运行循环时,使用CFRunLoopGetCurrent()
获取当前线程的运行循环,并在CFRunLoopRun()
之后调用IOHIDManagerOpen()
。
This guide from Apple可以帮助您开始使用this Q&A here on Stack Overflow。