Swift NSViewController响应mouseDown事件,但不响应keyDown事件

Ber*_*nem 8 cocoa

我正在尝试使用Swift和Cocoa为OS X创建一个应用程序.我希望应用程序响应关键事件而不将焦点放在文本字段中.我在Xcode中创建了一个带有故事板的新Cocoa项目,并将ViewController.swift类修改为以下内容:

import Cocoa

class ViewController: NSViewController {

    override func mouseDown(theEvent: NSEvent) {
        println( "Mouse Clicked" )
    }

    override func keyDown(theEvent: NSEvent) {
        println( "Key Pressed" )
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override var representedObject: AnyObject? {
        didSet {
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

当我运行程序时,当我点击窗口时我得到控制台输出,但是当我按任意键时我没有得到任何控制台输出.

所以我的问题是:为什么我的程序会响应鼠标事件而不是关键事件?我需要做些什么额外的步骤才能使关键事件像鼠标事件一样工作?

我的视图控制器似乎在响应器链中,因为它拦截了鼠标事件,所以这似乎不是问题所在.我在SE上找到了其他答案,说我需要继承NSView或NSWindow类.是否有可能在不这样做的情况下获得关键事件?

提前致谢.

编辑:除了接受的答案,从NSViewController Swift - Capture keydown是一个伟大,明确的解决方案.

Ren*_*ong 9

您观察到的差异源于Cocoa处理鼠标事件和键盘事件的事实.在事件调度过程的早期阶段,所有事件NSWindow都由系统发送到对象.对于鼠标事件,NSWindow将它们转发到用户单击的视图; 对于键盘事件,NSWindow将它们转发到当前键窗口的第一响应者.

a的初始第一响应者NSWindow是窗口本身.当用户点击a时NSView,NSWindow尝试通过发送acceptsFirstResponder消息使该视图成为第一个响应者.如果它返回YES,则单击的视图将成为第一响应者.

然而,"陷阱"是默认acceptsFirstResponder返回NO.由于普通NSView不会成为第一响应者,它不会收到键盘事件.因此,最简单的解决方案是将您的子类化NSView,重写acceptsFirstResponder以返回YES.